123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- #include <u.h>
- #include <libc.h>
- #include <venti.h>
- #include "queue.h"
- typedef struct Qel Qel;
- struct Qel
- {
- Qel *next;
- void *p;
- };
- struct Queue
- {
- int ref;
- int hungup;
- QLock lk;
- Rendez r;
- Qel *head;
- Qel *tail;
- };
- Queue*
- _vtqalloc(void)
- {
- Queue *q;
- q = vtmallocz(sizeof(Queue));
- q->r.l = &q->lk;
- q->ref = 1;
- return q;
- }
- Queue*
- _vtqincref(Queue *q)
- {
- qlock(&q->lk);
- q->ref++;
- qunlock(&q->lk);
- return q;
- }
- void
- _vtqdecref(Queue *q)
- {
- Qel *e;
-
- qlock(&q->lk);
- if(--q->ref > 0){
- qunlock(&q->lk);
- return;
- }
- assert(q->ref == 0);
- qunlock(&q->lk);
- /* Leaks the pointers e->p! */
- while(q->head){
- e = q->head;
- q->head = e->next;
- free(e);
- }
- free(q);
- }
- int
- _vtqsend(Queue *q, void *p)
- {
- Qel *e;
- e = vtmalloc(sizeof(Qel));
- 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*
- _vtqrecv(Queue *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;
- vtfree(e);
- return p;
- }
- void*
- _vtnbqrecv(Queue *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;
- vtfree(e);
- return p;
- }
- void
- _vtqhangup(Queue *q)
- {
- qlock(&q->lk);
- q->hungup = 1;
- rwakeupall(&q->r);
- qunlock(&q->lk);
- }
|