aboutsummaryrefslogtreecommitdiff
path: root/src/libmux/queue.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-12-06 18:08:52 +0000
committerrsc <devnull@localhost>2003-12-06 18:08:52 +0000
commitd3df308747ee4d1fcc063a348dcf1146b390bda7 (patch)
treea204b027256ec29b110caaa86100cbd701808b5b /src/libmux/queue.c
parente97ceade5e1bba5787e39429384336fa37797906 (diff)
downloadplan9port-d3df308747ee4d1fcc063a348dcf1146b390bda7.tar.gz
plan9port-d3df308747ee4d1fcc063a348dcf1146b390bda7.tar.bz2
plan9port-d3df308747ee4d1fcc063a348dcf1146b390bda7.zip
File system stuff.
Diffstat (limited to 'src/libmux/queue.c')
-rw-r--r--src/libmux/queue.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/libmux/queue.c b/src/libmux/queue.c
new file mode 100644
index 00000000..072f1860
--- /dev/null
+++ b/src/libmux/queue.c
@@ -0,0 +1,109 @@
+/* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
+/* See COPYRIGHT */
+
+#include <u.h>
+#include <libc.h>
+#include <mux.h>
+
+typedef struct Qel Qel;
+struct Qel
+{
+ Qel *next;
+ void *p;
+};
+
+struct Muxqueue
+{
+ int hungup;
+ QLock lk;
+ Rendez r;
+ Qel *head;
+ Qel *tail;
+};
+
+Muxqueue*
+_muxqalloc(void)
+{
+ Muxqueue *q;
+
+ q = mallocz(sizeof(Muxqueue), 1);
+ if(q == nil)
+ return nil;
+ q->r.l = &q->lk;
+ return q;
+}
+
+int
+_muxqsend(Muxqueue *q, void *p)
+{
+ Qel *e;
+
+ e = malloc(sizeof(Qel));
+ if(e == nil)
+ return -1;
+ qlock(&q->lk);
+ if(q->hungup){
+ werrstr("hungup queue");
+ qunlock(&q->lk);
+ return -1;
+ }
+ e->p = p;
+ e->next = nil;
+ if(q->head == nil)
+ q->head = e;
+ else
+ q->tail->next = e;
+ q->tail = e;
+ rwakeup(&q->r);
+ qunlock(&q->lk);
+ return 0;
+}
+
+void*
+_muxqrecv(Muxqueue *q)
+{
+ void *p;
+ Qel *e;
+
+ qlock(&q->lk);
+ while(q->head == nil && !q->hungup)
+ rsleep(&q->r);
+ if(q->hungup){
+ qunlock(&q->lk);
+ return nil;
+ }
+ e = q->head;
+ q->head = e->next;
+ qunlock(&q->lk);
+ p = e->p;
+ free(e);
+ return p;
+}
+
+void*
+_muxnbqrecv(Muxqueue *q)
+{
+ void *p;
+ Qel *e;
+
+ qlock(&q->lk);
+ if(q->head == nil){
+ qunlock(&q->lk);
+ return nil;
+ }
+ e = q->head;
+ q->head = e->next;
+ qunlock(&q->lk);
+ p = e->p;
+ free(e);
+ return p;
+}
+
+void
+_muxqhangup(Muxqueue *q)
+{
+ qlock(&q->lk);
+ q->hungup = 1;
+ rwakeupall(&q->r);
+ qunlock(&q->lk);
+}