Blob
1 #include <u.h>2 #include <libc.h>3 #include <venti.h>4 #include "queue.h"6 typedef struct Qel Qel;7 struct Qel8 {9 Qel *next;10 void *p;11 };13 struct Queue14 {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 void44 _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 int66 _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 else82 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;101 }102 e = q->head;103 q->head = e->next;104 qunlock(&q->lk);105 p = e->p;106 vtfree(e);107 return p;108 }110 void*111 _vtnbqrecv(Queue *q)112 {113 void *p;114 Qel *e;116 qlock(&q->lk);117 if(q->head == nil){118 qunlock(&q->lk);119 return nil;120 }121 e = q->head;122 q->head = e->next;123 qunlock(&q->lk);124 p = e->p;125 vtfree(e);126 return p;127 }129 void130 _vtqhangup(Queue *q)131 {132 qlock(&q->lk);133 q->hungup = 1;134 rwakeupall(&q->r);135 qunlock(&q->lk);136 }