-
Notifications
You must be signed in to change notification settings - Fork 0
/
blobqueue.c
84 lines (71 loc) · 1.71 KB
/
blobqueue.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <stdlib.h>
#include "mltypes.h"
#include "blobqueue.h"
void *blobqueue_new(void) {
blobqueue *bq = malloc(sizeof(blobqueue));
if (!bq) return 0;
bq->first = bq->last = 0;
bq->elem = 0;
return bq;
}
void blobqueue_destroy(bq)
blobqueue *bq;
{
void (*destructor)(void *);
void *entry;
while ((entry = blobqueue_pop(bq, BLOB_LAST, &destructor))) {
if (destructor)
destructor(entry);
}
free(bq);
}
int blobqueue_push(bq, qside, data, destructor)
blobqueue *bq;
ub1_t qside;
void *data;
void (*destructor)(void *);
{
blobqentry *entry = malloc(sizeof(blobqentry));
if (!entry) return 1;
entry->data = data;
entry->destructor = destructor;
if (!bq->last) {
entry->next = entry->prev = 0;
bq->first = bq->last = entry;
} else if (qside == BLOB_FIRST) {
entry->prev = 0;
entry->next = bq->first;
bq->first->prev = entry;
bq->first = entry;
} else /* BLOB_LAST */ {
entry->next = 0;
entry->prev = bq->last;
bq->last->next = entry;
bq->last = entry;
}
bq->elem++;
return 0;
}
void *blobqueue_pop (bq, qside, destructor)
blobqueue *bq;
ub1_t qside;
void (**destructor)(void *);
{
blobqentry *entry;
void *data;
if (!bq->last) return 0;
if (qside == BLOB_LAST) {
entry = bq->last;
if ((bq->last = entry->prev))
bq->last->next = 0;
} else {
entry = bq->first;
if ((bq->first = entry->next))
bq->first->prev = 0;
}
bq->elem--;
data = entry->data;
if (destructor) *destructor = entry->destructor;
free(entry);
return data;
}