mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
103 lines
1.2 KiB
C
103 lines
1.2 KiB
C
#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 hungup;
|
|
QLock lk;
|
|
Rendez r;
|
|
Qel *head;
|
|
Qel *tail;
|
|
};
|
|
|
|
Queue*
|
|
_vtqalloc(void)
|
|
{
|
|
Queue *q;
|
|
|
|
q = vtmallocz(sizeof(Queue));
|
|
q->r.l = &q->lk;
|
|
return 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);
|
|
}
|