20 #include <winpr/config.h>
22 #include <winpr/crt.h>
23 #include <winpr/assert.h>
25 #include <winpr/collections.h>
61 size_t Queue_Count(wQueue* queue)
78 void Queue_Lock(wQueue* queue)
81 if (queue->synchronized)
82 EnterCriticalSection(&queue->lock);
89 void Queue_Unlock(wQueue* queue)
92 if (queue->synchronized)
93 LeaveCriticalSection(&queue->lock);
100 HANDLE Queue_Event(wQueue* queue)
106 wObject* Queue_Object(wQueue* queue)
109 return &queue->object;
120 void Queue_Clear(wQueue* queue)
124 for (
size_t index = queue->head; index != queue->tail; index = (index + 1) % queue->capacity)
126 if (queue->object.fnObjectFree)
127 queue->object.fnObjectFree(queue->array[index]);
129 queue->array[index] = NULL;
133 queue->head = queue->tail = 0;
134 (void)ResetEvent(queue->event);
142 BOOL Queue_Contains(wQueue* queue,
const void* obj)
148 for (
size_t index = 0; index < queue->tail; index++)
150 if (queue->object.fnObjectEquals(queue->array[index], obj))
162 static BOOL Queue_EnsureCapacity(wQueue* queue,
size_t count)
166 if (queue->size + count >= queue->capacity)
168 const size_t old_capacity = queue->capacity;
169 size_t new_capacity = queue->capacity * queue->growthFactor;
170 void** newArray = NULL;
171 if (new_capacity < queue->size + count)
172 new_capacity = queue->size + count;
173 newArray = (
void**)realloc(queue->array,
sizeof(
void*) * new_capacity);
178 queue->capacity = new_capacity;
179 queue->array = newArray;
180 ZeroMemory(&(queue->array[old_capacity]), (new_capacity - old_capacity) *
sizeof(
void*));
183 if (queue->tail <= queue->head)
185 CopyMemory(&(queue->array[old_capacity]), queue->array, queue->tail *
sizeof(
void*));
186 queue->tail += old_capacity;
196 BOOL Queue_Enqueue(wQueue* queue,
const void* obj)
202 if (!Queue_EnsureCapacity(queue, 1))
205 if (queue->object.fnObjectNew)
206 queue->array[queue->tail] = queue->object.fnObjectNew(obj);
215 queue->array[queue->tail] = cnv.v;
217 queue->tail = (queue->tail + 1) % queue->capacity;
219 const BOOL signalSet = queue->size == 0;
223 (void)SetEvent(queue->event);
235 void* Queue_Dequeue(wQueue* queue)
243 obj = queue->array[queue->head];
244 queue->array[queue->head] = NULL;
245 queue->head = (queue->head + 1) % queue->capacity;
250 (void)ResetEvent(queue->event);
261 void* Queue_Peek(wQueue* queue)
268 obj = queue->array[queue->head];
275 void Queue_Discard(wQueue* queue)
280 obj = Queue_Dequeue(queue);
282 if (queue->object.fnObjectFree)
283 queue->object.fnObjectFree(obj);
287 static BOOL default_queue_equals(
const void* obj1,
const void* obj2)
289 return (obj1 == obj2);
296 wQueue* Queue_New(BOOL
synchronized, SSIZE_T capacity, SSIZE_T growthFactor)
299 wQueue* queue = NULL;
300 queue = (wQueue*)calloc(1,
sizeof(wQueue));
305 queue->synchronized =
synchronized;
307 queue->growthFactor = 2;
308 if (growthFactor > 0)
309 queue->growthFactor = (size_t)growthFactor;
313 if (!InitializeCriticalSectionAndSpinCount(&queue->lock, 4000))
315 queue->haveLock = TRUE;
316 if (!Queue_EnsureCapacity(queue, (
size_t)capacity))
319 queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
324 obj = Queue_Object(queue);
325 obj->fnObjectEquals = default_queue_equals;
329 WINPR_PRAGMA_DIAG_PUSH
330 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
332 WINPR_PRAGMA_DIAG_POP
336 void Queue_Free(wQueue* queue)
344 DeleteCriticalSection(&queue->lock);
346 (void)CloseHandle(queue->event);
This struct contains function pointer to initialize/free objects.