blob: 935b6f1c41f4473a9dbd025f6aa433f379758fe9 (
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
|
#include <mbgl/util/uv-messenger.h>
#include <mbgl/util/queue.h>
#include <stdlib.h>
#include <assert.h>
typedef struct {
void *data;
void *queue[2];
} uv__messenger_item_t;
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
void uv__messenger_callback(uv_async_t *async, int status) {
#pragma clang diagnostic pop
#else
void uv__messenger_callback(uv_async_t *async) {
#endif
uv_messenger_t *msgr = (uv_messenger_t *)async->data;
uv__messenger_item_t *item;
QUEUE *head;
while (1) {
uv_mutex_lock(&msgr->mutex);
if (QUEUE_EMPTY(&msgr->queue)) {
uv_mutex_unlock(&msgr->mutex);
break;
}
head = QUEUE_HEAD(&msgr->queue);
item = QUEUE_DATA(head, uv__messenger_item_t, queue);
QUEUE_REMOVE(head);
uv_mutex_unlock(&msgr->mutex);
msgr->callback(item->data);
free(item);
}
}
int uv_messenger_init(uv_loop_t *loop, uv_messenger_t *msgr, uv_messenger_cb callback) {
int ret = uv_mutex_init(&msgr->mutex);
if (ret < 0) {
return ret;
}
msgr->callback = callback;
msgr->stop_callback = NULL;
QUEUE_INIT(&msgr->queue);
msgr->async.data = msgr;
return uv_async_init(loop, &msgr->async, uv__messenger_callback);
}
void uv_messenger_send(uv_messenger_t *msgr, void *data) {
uv__messenger_item_t *item = (uv__messenger_item_t *)malloc(sizeof(uv__messenger_item_t));
item->data = data;
uv_mutex_lock(&msgr->mutex);
QUEUE_INSERT_TAIL(&msgr->queue, &item->queue);
uv_mutex_unlock(&msgr->mutex);
uv_async_send(&msgr->async);
}
void uv_messenger_ref(uv_messenger_t *msgr) {
uv_ref((uv_handle_t *)&msgr->async);
}
void uv_messenger_unref(uv_messenger_t *msgr) {
uv_unref((uv_handle_t *)&msgr->async);
}
void uv__messenger_stop_callback(uv_handle_t *handle) {
uv_messenger_t *msgr = (uv_messenger_t *)handle->data;
msgr->stop_callback(msgr);
}
void uv_messenger_stop(uv_messenger_t *msgr, uv_messenger_stop_cb stop_callback) {
assert(!msgr->stop_callback);
msgr->stop_callback = stop_callback;
uv_close((uv_handle_t *)&msgr->async, uv__messenger_stop_callback);
}
|