queue.c (1401B)
1 /* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */ 2 /* See COPYRIGHT */ 3 4 #include <u.h> 5 #include <libc.h> 6 #include <mux.h> 7 8 typedef struct Qel Qel; 9 struct Qel 10 { 11 Qel *next; 12 void *p; 13 }; 14 15 struct Muxqueue 16 { 17 int hungup; 18 QLock lk; 19 Rendez r; 20 Qel *head; 21 Qel *tail; 22 }; 23 24 Muxqueue* 25 _muxqalloc(void) 26 { 27 Muxqueue *q; 28 29 q = mallocz(sizeof(Muxqueue), 1); 30 if(q == nil) 31 return nil; 32 q->r.l = &q->lk; 33 return q; 34 } 35 36 int 37 _muxqsend(Muxqueue *q, void *p) 38 { 39 Qel *e; 40 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 } 62 63 void* 64 _muxqrecv(Muxqueue *q) 65 { 66 void *p; 67 Qel *e; 68 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 } 83 84 int 85 _muxnbqrecv(Muxqueue *q, void **vp) 86 { 87 void *p; 88 Qel *e; 89 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; 103 } 104 105 void 106 _muxqhangup(Muxqueue *q) 107 { 108 qlock(&q->lk); 109 q->hungup = 1; 110 rwakeupall(&q->r); 111 qunlock(&q->lk); 112 }