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 hungup;
16 QLock lk;
17 Rendez r;
18 Qel *head;
19 Qel *tail;
20 };
22 Queue*
23 _vtqalloc(void)
24 {
25 Queue *q;
27 q = vtmallocz(sizeof(Queue));
28 q->r.l = &q->lk;
29 return q;
30 }
32 int
33 _vtqsend(Queue *q, void *p)
34 {
35 Qel *e;
37 e = vtmalloc(sizeof(Qel));
38 qlock(&q->lk);
39 if(q->hungup){
40 werrstr("hungup queue");
41 qunlock(&q->lk);
42 return -1;
43 }
44 e->p = p;
45 e->next = nil;
46 if(q->head == nil)
47 q->head = e;
48 else
49 q->tail->next = e;
50 q->tail = e;
51 rwakeup(&q->r);
52 qunlock(&q->lk);
53 return 0;
54 }
56 void*
57 _vtqrecv(Queue *q)
58 {
59 void *p;
60 Qel *e;
62 qlock(&q->lk);
63 while(q->head == nil && !q->hungup)
64 rsleep(&q->r);
65 if(q->hungup){
66 qunlock(&q->lk);
67 return nil;
68 }
69 e = q->head;
70 q->head = e->next;
71 qunlock(&q->lk);
72 p = e->p;
73 vtfree(e);
74 return p;
75 }
77 void*
78 _vtnbqrecv(Queue *q)
79 {
80 void *p;
81 Qel *e;
83 qlock(&q->lk);
84 if(q->head == nil){
85 qunlock(&q->lk);
86 return nil;
87 }
88 e = q->head;
89 q->head = e->next;
90 qunlock(&q->lk);
91 p = e->p;
92 vtfree(e);
93 return p;
94 }
96 void
97 _vtqhangup(Queue *q)
98 {
99 qlock(&q->lk);
100 q->hungup = 1;
101 rwakeupall(&q->r);
102 qunlock(&q->lk);