blob: a1fde5253f0ca357c1bed380e75c7ead51bcf03c (
plain)
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#include "itc.h"
void itc_chan_create(itc_chan *chan)
{
memset(chan, 0, sizeof(itc_chan));
chan->mutex = SDL_CreateMutex();
assert(chan->mutex);
chan->sem = SDL_CreateSemaphore(0);
assert(chan->sem);
}
void itc_chan_destroy(itc_chan *chan)
{
// todo: free queue
SDL_DestroySemaphore(chan->sem);
SDL_DestroyMutex(chan->mutex);
}
void itc_chan_push(itc_chan *chan, int number, void *data)
{
itc_message *msg;
msg = calloc(1, sizeof(itc_message));
assert(msg);
msg->number = number;
msg->data = data;
SDL_LockMutex(chan->mutex);
if (!chan->oldest) {
chan->oldest = msg;
chan->newest = msg;
} else {
/*
* head <---> ... <---> tail
*
*/
chan->newest->newer = msg;
msg->older = chan->newest;
chan->newest = msg;
}
SDL_SemPost(chan->sem);
SDL_UnlockMutex(chan->mutex);
}
int itc_chan_pop(itc_chan *chan, int *number, void **data)
{
itc_message *msg;
SDL_LockMutex(chan->mutex);
if (!chan->oldest) {
SDL_UnlockMutex(chan->mutex);
return 1;
}
msg = chan->oldest;
if (msg->newer) {
msg->newer->older = NULL;
chan->oldest = msg->newer;
} else {
chan->newest = NULL;
chan->oldest = NULL;
}
SDL_SemWait(chan->sem); // should be instant
SDL_UnlockMutex(chan->mutex);
*number = msg->number;
*data = msg->data;
free(msg);
return 0;
}
int itc_chan_pop_block(itc_chan *chan, int *number, void **data)
{
itc_message *msg;
SDL_SemWait(chan->sem);
SDL_LockMutex(chan->mutex);
if (!chan->oldest) {
SDL_UnlockMutex(chan->mutex);
return 1;
}
msg = chan->oldest;
if (msg->newer) {
msg->newer->older = NULL;
chan->oldest = msg->newer;
} else {
chan->newest = NULL;
chan->oldest = NULL;
}
SDL_UnlockMutex(chan->mutex);
*number = msg->number;
*data = msg->data;
free(msg);
return 0;
}
|