Blob


1 /* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
2 /* See COPYRIGHT */
4 #include <u.h>
5 #include <libc.h>
6 #include <mux.h>
8 typedef struct Qel Qel;
9 struct Qel
10 {
11 Qel *next;
12 void *p;
13 };
15 struct Muxqueue
16 {
17 int hungup;
18 QLock lk;
19 Rendez r;
20 Qel *head;
21 Qel *tail;
22 };
24 Muxqueue*
25 _muxqalloc(void)
26 {
27 Muxqueue *q;
29 q = mallocz(sizeof(Muxqueue), 1);
30 if(q == nil)
31 return nil;
32 q->r.l = &q->lk;
33 return q;
34 }
36 int
37 _muxqsend(Muxqueue *q, void *p)
38 {
39 Qel *e;
41 e = malloc(sizeof(Qel));
42 if(e == nil)
43 return -1;
44 qlock(&q->lk);
45 if(q->hungup){
46 werrstr("hungup queue");
47 qunlock(&q->lk);
48 free(e);
49 return -1;
50 }
51 e->p = p;
52 e->next = nil;
53 if(q->head == nil)
54 q->head = e;
55 else
56 q->tail->next = e;
57 q->tail = e;
58 rwakeup(&q->r);
59 qunlock(&q->lk);
60 return 0;
61 }
63 void*
64 _muxqrecv(Muxqueue *q)
65 {
66 void *p;
67 Qel *e;
69 qlock(&q->lk);
70 while(q->head == nil && !q->hungup)
71 rsleep(&q->r);
72 if(q->hungup){
73 qunlock(&q->lk);
74 return nil;
75 }
76 e = q->head;
77 q->head = e->next;
78 qunlock(&q->lk);
79 p = e->p;
80 free(e);
81 return p;
82 }
84 int
85 _muxnbqrecv(Muxqueue *q, void **vp)
86 {
87 void *p;
88 Qel *e;
90 qlock(&q->lk);
91 if(q->head == nil){
92 qunlock(&q->lk);
93 *vp = nil;
94 return q->hungup;
95 }
96 e = q->head;
97 q->head = e->next;
98 qunlock(&q->lk);
99 p = e->p;
100 free(e);
101 *vp = p;
102 return 1;
105 void
106 _muxqhangup(Muxqueue *q)
108 qlock(&q->lk);
109 q->hungup = 1;
110 rwakeupall(&q->r);
111 qunlock(&q->lk);