Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/libventi/queue.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}