correct dangling pointer race (Bakul Shah)
This commit is contained in:
parent
8ecb4ffe4c
commit
4f6d2bb1e8
4 changed files with 36 additions and 6 deletions
|
|
@ -46,5 +46,6 @@ vtfreeconn(VtConn *z)
|
||||||
packetfree(z->part);
|
packetfree(z->part);
|
||||||
vtfree(z->version);
|
vtfree(z->version);
|
||||||
vtfree(z->sid);
|
vtfree(z->sid);
|
||||||
|
qunlock(&z->lk);
|
||||||
vtfree(z);
|
vtfree(z);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ struct Qel
|
||||||
|
|
||||||
struct Queue
|
struct Queue
|
||||||
{
|
{
|
||||||
|
int ref;
|
||||||
int hungup;
|
int hungup;
|
||||||
QLock lk;
|
QLock lk;
|
||||||
Rendez r;
|
Rendez r;
|
||||||
|
|
@ -26,14 +27,32 @@ _vtqalloc(void)
|
||||||
|
|
||||||
q = vtmallocz(sizeof(Queue));
|
q = vtmallocz(sizeof(Queue));
|
||||||
q->r.l = &q->lk;
|
q->r.l = &q->lk;
|
||||||
|
q->ref = 1;
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
Queue*
|
||||||
|
_vtqincref(Queue *q)
|
||||||
|
{
|
||||||
|
qlock(&q->lk);
|
||||||
|
q->ref++;
|
||||||
|
qunlock(&q->lk);
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_vtqfree(Queue *q)
|
_vtqdecref(Queue *q)
|
||||||
{
|
{
|
||||||
Qel *e;
|
Qel *e;
|
||||||
|
|
||||||
|
qlock(&q->lk);
|
||||||
|
if(--q->ref > 0){
|
||||||
|
qunlock(&q->lk);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(q->ref == 0);
|
||||||
|
qunlock(&q->lk);
|
||||||
|
|
||||||
/* Leaks the pointers e->p! */
|
/* Leaks the pointers e->p! */
|
||||||
while(q->head){
|
while(q->head){
|
||||||
e = q->head;
|
e = q->head;
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,5 @@ int _vtqsend(Queue*, void*);
|
||||||
void *_vtqrecv(Queue*);
|
void *_vtqrecv(Queue*);
|
||||||
void _vtqhangup(Queue*);
|
void _vtqhangup(Queue*);
|
||||||
void *_vtnbqrecv(Queue*);
|
void *_vtnbqrecv(Queue*);
|
||||||
void _vtqfree(Queue*);
|
void _vtqdecref(Queue*);
|
||||||
|
Queue *_vtqincref(Queue*);
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ vtrecvproc(void *v)
|
||||||
_vtqhangup(q);
|
_vtqhangup(q);
|
||||||
while((p = _vtnbqrecv(q)) != nil)
|
while((p = _vtnbqrecv(q)) != nil)
|
||||||
packetfree(p);
|
packetfree(p);
|
||||||
_vtqfree(q);
|
_vtqdecref(q);
|
||||||
z->readq = nil;
|
z->readq = nil;
|
||||||
rwakeup(&z->rpcfork);
|
rwakeup(&z->rpcfork);
|
||||||
qunlock(&z->lk);
|
qunlock(&z->lk);
|
||||||
|
|
@ -178,7 +178,7 @@ vtsendproc(void *v)
|
||||||
_vtqhangup(q);
|
_vtqhangup(q);
|
||||||
while((p = _vtnbqrecv(q)) != nil)
|
while((p = _vtnbqrecv(q)) != nil)
|
||||||
packetfree(p);
|
packetfree(p);
|
||||||
_vtqfree(q);
|
_vtqdecref(q);
|
||||||
z->writeq = nil;
|
z->writeq = nil;
|
||||||
rwakeup(&z->rpcfork);
|
rwakeup(&z->rpcfork);
|
||||||
qunlock(&z->lk);
|
qunlock(&z->lk);
|
||||||
|
|
@ -189,6 +189,7 @@ Packet*
|
||||||
vtrecv(VtConn *z)
|
vtrecv(VtConn *z)
|
||||||
{
|
{
|
||||||
Packet *p;
|
Packet *p;
|
||||||
|
Queue *q;
|
||||||
|
|
||||||
qlock(&z->lk);
|
qlock(&z->lk);
|
||||||
if(z->state != VtStateConnected){
|
if(z->state != VtStateConnected){
|
||||||
|
|
@ -197,8 +198,11 @@ vtrecv(VtConn *z)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
if(z->readq){
|
if(z->readq){
|
||||||
|
q = _vtqincref(z->readq);
|
||||||
qunlock(&z->lk);
|
qunlock(&z->lk);
|
||||||
return _vtqrecv(z->readq);
|
p = _vtqrecv(q);
|
||||||
|
_vtqdecref(q);
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
qlock(&z->inlk);
|
qlock(&z->inlk);
|
||||||
|
|
@ -213,6 +217,8 @@ vtrecv(VtConn *z)
|
||||||
int
|
int
|
||||||
vtsend(VtConn *z, Packet *p)
|
vtsend(VtConn *z, Packet *p)
|
||||||
{
|
{
|
||||||
|
Queue *q;
|
||||||
|
|
||||||
qlock(&z->lk);
|
qlock(&z->lk);
|
||||||
if(z->state != VtStateConnected){
|
if(z->state != VtStateConnected){
|
||||||
packetfree(p);
|
packetfree(p);
|
||||||
|
|
@ -221,11 +227,14 @@ vtsend(VtConn *z, Packet *p)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(z->writeq){
|
if(z->writeq){
|
||||||
|
q = _vtqincref(z->writeq);
|
||||||
qunlock(&z->lk);
|
qunlock(&z->lk);
|
||||||
if(_vtqsend(z->writeq, p) < 0){
|
if(_vtqsend(q, p) < 0){
|
||||||
|
_vtqdecref(q);
|
||||||
packetfree(p);
|
packetfree(p);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
_vtqdecref(q);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue