commit - 8ecb4ffe4c618bb484299a4a3b29f2a991903e53
commit + 4f6d2bb1e8e38aaeeeabb159272da19718bfb05d
blob - 5b6d5436c41f99f1f681dd1701fccc2ea9303ea6
blob + e488c6db6a2c05803e56e1bbe114d4e8f751d25f
--- src/libventi/conn.c
+++ src/libventi/conn.c
packetfree(z->part);
vtfree(z->version);
vtfree(z->sid);
+ qunlock(&z->lk);
vtfree(z);
}
blob - 3a1f6ea56d71bacf8dd503fe2ad6de5ebcb29972
blob + bba630324e0cd1d6cfd9f456cb6b347136b38295
--- src/libventi/queue.c
+++ src/libventi/queue.c
struct Queue
{
+ int ref;
int hungup;
QLock lk;
Rendez r;
q = vtmallocz(sizeof(Queue));
q->r.l = &q->lk;
+ q->ref = 1;
return q;
}
+Queue*
+_vtqincref(Queue *q)
+{
+ qlock(&q->lk);
+ q->ref++;
+ qunlock(&q->lk);
+ return q;
+}
+
void
-_vtqfree(Queue *q)
+_vtqdecref(Queue *q)
{
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! */
while(q->head){
e = q->head;
blob - 2807783bddf7184c2426e36418c8f4156cf2bd2b
blob + 90ee1402cc6527a31b6b439fa1e8a2ba43046ff8
--- src/libventi/queue.h
+++ src/libventi/queue.h
void *_vtqrecv(Queue*);
void _vtqhangup(Queue*);
void *_vtnbqrecv(Queue*);
-void _vtqfree(Queue*);
+void _vtqdecref(Queue*);
+Queue *_vtqincref(Queue*);
blob - 7ada51af76155c6e1b84cf213292b75bd83e4ccc
blob + 70cc8272770eae633b6297e45362de2fde73b597
--- src/libventi/send.c
+++ src/libventi/send.c
_vtqhangup(q);
while((p = _vtnbqrecv(q)) != nil)
packetfree(p);
- _vtqfree(q);
+ _vtqdecref(q);
z->readq = nil;
rwakeup(&z->rpcfork);
qunlock(&z->lk);
_vtqhangup(q);
while((p = _vtnbqrecv(q)) != nil)
packetfree(p);
- _vtqfree(q);
+ _vtqdecref(q);
z->writeq = nil;
rwakeup(&z->rpcfork);
qunlock(&z->lk);
vtrecv(VtConn *z)
{
Packet *p;
+ Queue *q;
qlock(&z->lk);
if(z->state != VtStateConnected){
return nil;
}
if(z->readq){
+ q = _vtqincref(z->readq);
qunlock(&z->lk);
- return _vtqrecv(z->readq);
+ p = _vtqrecv(q);
+ _vtqdecref(q);
+ return p;
}
qlock(&z->inlk);
int
vtsend(VtConn *z, Packet *p)
{
+ Queue *q;
+
qlock(&z->lk);
if(z->state != VtStateConnected){
packetfree(p);
return -1;
}
if(z->writeq){
+ q = _vtqincref(z->writeq);
qunlock(&z->lk);
- if(_vtqsend(z->writeq, p) < 0){
+ if(_vtqsend(q, p) < 0){
+ _vtqdecref(q);
packetfree(p);
return -1;
}
+ _vtqdecref(q);
return 0;
}