1 |
|
2 |
|
3 |
|
4 | #include <string.h>
|
5 | #include <stdio.h>
|
6 | #include <uv.h>
|
7 | #include <stdlib.h>
|
8 | #if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__) || defined(_AIX)
|
9 | #include <unistd.h>
|
10 | #endif
|
11 |
|
12 | enum types {
|
13 | kItemTypeNONE,
|
14 | kItemTypeNumber,
|
15 | kItemTypePointer,
|
16 | kItemTypeQUIT
|
17 | };
|
18 |
|
19 | struct typeQueueItem {
|
20 | int itemType;
|
21 | typeQueueItem* next;
|
22 | union {
|
23 | void* asPtr;
|
24 | double asNumber;
|
25 | };
|
26 | };
|
27 | typedef struct typeQueueItem typeQueueItem;
|
28 |
|
29 | typedef struct {
|
30 | typeQueueItem* first;
|
31 | typeQueueItem* last;
|
32 | uv_mutex_t queueLock;
|
33 | long int id;
|
34 | volatile long int length;
|
35 | } typeQueue;
|
36 |
|
37 | static typeQueue* queuesPool= NULL;
|
38 | static typeQueue* freeItemsQueue= NULL;
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | static void queue_push (typeQueueItem* qitem, typeQueue* queue) {
|
44 | qitem->next= NULL;
|
45 |
|
46 | uv_mutex_lock(&queue->queueLock);
|
47 | if (queue->last) {
|
48 | queue->last->next= qitem;
|
49 | }
|
50 | else {
|
51 | queue->first= qitem;
|
52 | }
|
53 | queue->last= qitem;
|
54 | queue->length++;
|
55 | uv_mutex_unlock(&queue->queueLock);
|
56 | }
|
57 |
|
58 |
|
59 |
|
60 |
|
61 | static typeQueueItem* queue_pull (typeQueue* queue) {
|
62 | typeQueueItem* qitem;
|
63 |
|
64 | uv_mutex_lock(&queue->queueLock);
|
65 | if ((qitem= queue->first)) {
|
66 | if (queue->last == qitem) {
|
67 | queue->first= queue->last= NULL;
|
68 | }
|
69 | else {
|
70 | queue->first= qitem->next;
|
71 | }
|
72 | queue->length--;
|
73 | qitem->next= NULL;
|
74 | }
|
75 | uv_mutex_unlock(&queue->queueLock);
|
76 |
|
77 | return qitem;
|
78 | }
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | static typeQueueItem* nuItem (int itemType, void* item) {
|
84 |
|
85 | typeQueueItem* qitem= queue_pull(freeItemsQueue);
|
86 | if (!qitem) {
|
87 | qitem= (typeQueueItem*) calloc(1, sizeof(typeQueueItem));
|
88 | }
|
89 |
|
90 | qitem->next= NULL;
|
91 | qitem->itemType= itemType;
|
92 | if (itemType == kItemTypeNumber) {
|
93 | qitem->asNumber= *((double*) item);
|
94 | }
|
95 | else if (itemType == kItemTypePointer) {
|
96 | qitem->asPtr= item;
|
97 | }
|
98 |
|
99 | return qitem;
|
100 | }
|
101 |
|
102 |
|
103 |
|
104 |
|
105 | static void destroyItem (typeQueueItem* qitem) {
|
106 |
|
107 | if (freeItemsQueue) {
|
108 | queue_push(qitem, freeItemsQueue);
|
109 | }
|
110 | else {
|
111 | free(qitem);
|
112 | }
|
113 | }
|
114 |
|
115 |
|
116 |
|
117 |
|
118 | static typeQueue* nuQueue (long int id) {
|
119 |
|
120 | typeQueue* queue= NULL;
|
121 | typeQueueItem* qitem= NULL;
|
122 | if (queuesPool && queuesPool->first) qitem= queue_pull(queuesPool);
|
123 | if (qitem) {
|
124 | queue= (typeQueue*) qitem->asPtr;
|
125 | destroyItem(qitem);
|
126 | }
|
127 | else {
|
128 | queue= (typeQueue*) calloc(1, sizeof(typeQueue));
|
129 | uv_mutex_init(&queue->queueLock);
|
130 | }
|
131 |
|
132 | queue->id= id;
|
133 | queue->length= 0;
|
134 | queue->first= queue->last= NULL;
|
135 | return queue;
|
136 | }
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 | static void initQueues (void) {
|
154 | freeItemsQueue= nuQueue(-2);
|
155 |
|
156 | }
|
157 |
|
158 |
|
159 |
|
160 |
|