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((
void*)queue->array,
sizeof(
void*) * new_capacity);
178 queue->capacity = new_capacity;
179 queue->array = newArray;
180 ZeroMemory((
void*)&(queue->array[old_capacity]),
181 (new_capacity - old_capacity) *
sizeof(
void*));
184 if (queue->tail <= queue->head)
186 CopyMemory((
void*)&(queue->array[old_capacity]), (
void*)queue->array,
187 queue->tail *
sizeof(
void*));
188 queue->tail += old_capacity;
198 BOOL Queue_Enqueue(wQueue* queue,
const void* obj)
204 if (!Queue_EnsureCapacity(queue, 1))
207 if (queue->object.fnObjectNew)
208 queue->array[queue->tail] = queue->object.fnObjectNew(obj);
217 queue->array[queue->tail] = cnv.v;
219 queue->tail = (queue->tail + 1) % queue->capacity;
221 const BOOL signalSet = queue->size == 0;
225 (void)SetEvent(queue->event);
237 void* Queue_Dequeue(wQueue* queue)
245 obj = queue->array[queue->head];
246 queue->array[queue->head] = NULL;
247 queue->head = (queue->head + 1) % queue->capacity;
252 (void)ResetEvent(queue->event);
263 void* Queue_Peek(wQueue* queue)
270 obj = queue->array[queue->head];
277 void Queue_Discard(wQueue* queue)
282 obj = Queue_Dequeue(queue);
284 if (queue->object.fnObjectFree)
285 queue->object.fnObjectFree(obj);
289 static BOOL default_queue_equals(
const void* obj1,
const void* obj2)
291 return (obj1 == obj2);
298 wQueue* Queue_New(BOOL
synchronized, SSIZE_T capacity, SSIZE_T growthFactor)
301 wQueue* queue = NULL;
302 queue = (wQueue*)calloc(1,
sizeof(wQueue));
307 queue->synchronized =
synchronized;
309 queue->growthFactor = 2;
310 if (growthFactor > 0)
311 queue->growthFactor = (size_t)growthFactor;
315 if (!InitializeCriticalSectionAndSpinCount(&queue->lock, 4000))
317 queue->haveLock = TRUE;
318 if (!Queue_EnsureCapacity(queue, (
size_t)capacity))
321 queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
326 obj = Queue_Object(queue);
327 obj->fnObjectEquals = default_queue_equals;
331 WINPR_PRAGMA_DIAG_PUSH
332 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
334 WINPR_PRAGMA_DIAG_POP
338 void Queue_Free(wQueue* queue)
346 DeleteCriticalSection(&queue->lock);
348 (void)CloseHandle(queue->event);
349 free((
void*)queue->array);
This struct contains function pointer to initialize/free objects.