aboutsummaryrefslogtreecommitdiff
path: root/src/libventi/queue.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2007-04-08 01:30:26 +0000
committerrsc <devnull@localhost>2007-04-08 01:30:26 +0000
commit4f6d2bb1e8e38aaeeeabb159272da19718bfb05d (patch)
tree100758b863425d60071fea95e1ffb3a6ed0ada15 /src/libventi/queue.c
parent8ecb4ffe4c618bb484299a4a3b29f2a991903e53 (diff)
correct dangling pointer race (Bakul Shah)
Diffstat (limited to 'src/libventi/queue.c')
-rw-r--r--src/libventi/queue.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/libventi/queue.c b/src/libventi/queue.c
index 3a1f6ea5..bba63032 100644
--- a/src/libventi/queue.c
+++ b/src/libventi/queue.c
@@ -12,6 +12,7 @@ struct Qel
struct Queue
{
+ int ref;
int hungup;
QLock lk;
Rendez r;
@@ -26,14 +27,32 @@ _vtqalloc(void)
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;