plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }