URI:
       tqueue.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tqueue.c (1570B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <venti.h>
            4 #include "queue.h"
            5 
            6 typedef struct Qel Qel;
            7 struct Qel
            8 {
            9         Qel *next;
           10         void *p;
           11 };
           12 
           13 struct Queue
           14 {
           15         int ref;
           16         int hungup;
           17         QLock lk;
           18         Rendez r;
           19         Qel *head;
           20         Qel *tail;
           21 };
           22 
           23 Queue*
           24 _vtqalloc(void)
           25 {
           26         Queue *q;
           27 
           28         q = vtmallocz(sizeof(Queue));
           29         q->r.l = &q->lk;
           30         q->ref = 1;
           31         return q;
           32 }
           33 
           34 Queue*
           35 _vtqincref(Queue *q)
           36 {
           37         qlock(&q->lk);
           38         q->ref++;
           39         qunlock(&q->lk);
           40         return q;
           41 }
           42 
           43 void
           44 _vtqdecref(Queue *q)
           45 {
           46         Qel *e;
           47 
           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);
           55 
           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 }
           64 
           65 int
           66 _vtqsend(Queue *q, void *p)
           67 {
           68         Qel *e;
           69 
           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         else
           82                 q->tail->next = e;
           83         q->tail = e;
           84         rwakeup(&q->r);
           85         qunlock(&q->lk);
           86         return 0;
           87 }
           88 
           89 void*
           90 _vtqrecv(Queue *q)
           91 {
           92         void *p;
           93         Qel *e;
           94 
           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 }
          109 
          110 void*
          111 _vtnbqrecv(Queue *q)
          112 {
          113         void *p;
          114         Qel *e;
          115 
          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 }
          128 
          129 void
          130 _vtqhangup(Queue *q)
          131 {
          132         qlock(&q->lk);
          133         q->hungup = 1;
          134         rwakeupall(&q->r);
          135         qunlock(&q->lk);
          136 }