UNPKG

2.77 kBtext/x-cView Raw
1//2011-11 Proyectos Equis Ka, s.l., jorge@jorgechamorro.com
2//queues_a_gogo.cc
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
12enum types {
13 kItemTypeNONE,
14 kItemTypeNumber,
15 kItemTypePointer,
16 kItemTypeQUIT
17};
18
19struct typeQueueItem {
20 int itemType;
21 typeQueueItem* next;
22 union {
23 void* asPtr;
24 double asNumber;
25 };
26};
27typedef struct typeQueueItem typeQueueItem;
28
29typedef struct {
30 typeQueueItem* first;
31 typeQueueItem* last;
32 uv_mutex_t queueLock;
33 long int id;
34 volatile long int length;
35} typeQueue;
36
37static typeQueue* queuesPool= NULL;
38static typeQueue* freeItemsQueue= NULL;
39
40
41
42
43static 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
61static 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
83static 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
105static 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
118static 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
141static void destroyQueue (typeQueue* queue) {
142 if (queuesPool) {
143 queue_push(nuItem(kItemTypePointer, queue), queuesPool);
144 }
145 else {
146 free(queue);
147 }
148}
149
150*/
151
152
153static void initQueues (void) {
154 freeItemsQueue= nuQueue(-2); //MUST be created before queuesPool
155 //queuesPool= nuQueue(-1);
156}
157
158
159
160