Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
4 #include "queue.h"
6 typedef struct Qel Qel;
7 struct Qel
8 {
9 Qel *next;
10 void *p;
11 };
13 struct Queue
14 {
15 int ref;
16 int hungup;
17 QLock lk;
18 Rendez r;
19 Qel *head;
20 Qel *tail;
21 };
23 Queue*
24 _vtqalloc(void)
25 {
26 Queue *q;
28 q = vtmallocz(sizeof(Queue));
29 q->r.l = &q->lk;
30 q->ref = 1;
31 return q;
32 }
34 Queue*
35 _vtqincref(Queue *q)
36 {
37 qlock(&q->lk);
38 q->ref++;
39 qunlock(&q->lk);
40 return q;
41 }
43 void
44 _vtqdecref(Queue *q)
45 {
46 Qel *e;
48 qlock(&q->lk);
49 if(--q->ref > 0){
50 qunlock(&q->lk);
51 return;
52 }
53 assert(q->ref == 0);
54 qunlock(&q->lk);
56 /* Leaks the pointers e->p! */
57 while(q->head){
58 e = q->head;
59 q->head = e->next;
60 free(e);
61 }
62 free(q);
63 }
65 int
66 _vtqsend(Queue *q, void *p)
67 {
68 Qel *e;
70 e = vtmalloc(sizeof(Qel));
71 qlock(&q->lk);
72 if(q->hungup){
73 werrstr("hungup queue");
74 qunlock(&q->lk);
75 return -1;
76 }
77 e->p = p;
78 e->next = nil;
79 if(q->head == nil)
80 q->head = e;
81 else
82 q->tail->next = e;
83 q->tail = e;
84 rwakeup(&q->r);
85 qunlock(&q->lk);
86 return 0;
87 }
89 void*
90 _vtqrecv(Queue *q)
91 {
92 void *p;
93 Qel *e;
95 qlock(&q->lk);
96 while(q->head == nil && !q->hungup)
97 rsleep(&q->r);
98 if(q->hungup){
99 qunlock(&q->lk);
100 return nil;
102 e = q->head;
103 q->head = e->next;
104 qunlock(&q->lk);
105 p = e->p;
106 vtfree(e);
107 return p;
110 void*
111 _vtnbqrecv(Queue *q)
113 void *p;
114 Qel *e;
116 qlock(&q->lk);
117 if(q->head == nil){
118 qunlock(&q->lk);
119 return nil;
121 e = q->head;
122 q->head = e->next;
123 qunlock(&q->lk);
124 p = e->p;
125 vtfree(e);
126 return p;
129 void
130 _vtqhangup(Queue *q)
132 qlock(&q->lk);
133 q->hungup = 1;
134 rwakeupall(&q->r);
135 qunlock(&q->lk);