Merge pull request #1801 from hardening/queue_stack_fixes
Fixes for queue and stack
This commit is contained in:
commit
86975b5605
@ -659,7 +659,7 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
|
||||
drive->path = path;
|
||||
|
||||
drive->files = ListDictionary_New(TRUE);
|
||||
ListDictionary_Object(drive->files)->fnObjectFree = (OBJECT_FREE_FN) drive_file_free;
|
||||
ListDictionary_ValueObject(drive->files)->fnObjectFree = (OBJECT_FREE_FN) drive_file_free;
|
||||
|
||||
drive->IrpQueue = MessageQueue_New(NULL);
|
||||
drive->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL);
|
||||
|
@ -55,7 +55,7 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
||||
|
||||
devman->devices = ListDictionary_New(TRUE);
|
||||
|
||||
ListDictionary_Object(devman->devices)->fnObjectFree =
|
||||
ListDictionary_ValueObject(devman->devices)->fnObjectFree =
|
||||
(OBJECT_FREE_FN) devman_device_free;
|
||||
|
||||
return devman;
|
||||
|
@ -39,7 +39,7 @@ typedef void* (*OBJECT_NEW_FN)(void);
|
||||
typedef void (*OBJECT_INIT_FN)(void* obj);
|
||||
typedef void (*OBJECT_UNINIT_FN)(void* obj);
|
||||
typedef void (*OBJECT_FREE_FN)(void* obj);
|
||||
typedef void (*OBJECT_EQUALS_FN)(void* objA, void* objB);
|
||||
typedef BOOL (*OBJECT_EQUALS_FN)(void* objA, void* objB);
|
||||
|
||||
struct _wObject
|
||||
{
|
||||
@ -83,7 +83,7 @@ WINPR_API void Queue_Clear(wQueue* queue);
|
||||
|
||||
WINPR_API BOOL Queue_Contains(wQueue* queue, void* obj);
|
||||
|
||||
WINPR_API void Queue_Enqueue(wQueue* queue, void* obj);
|
||||
WINPR_API BOOL Queue_Enqueue(wQueue* queue, void* obj);
|
||||
WINPR_API void* Queue_Dequeue(wQueue* queue);
|
||||
|
||||
WINPR_API void* Queue_Peek(wQueue* queue);
|
||||
@ -192,18 +192,20 @@ struct _wListDictionary
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
wListDictionaryItem* head;
|
||||
wObject object;
|
||||
wObject objectKey;
|
||||
wObject objectValue;
|
||||
};
|
||||
typedef struct _wListDictionary wListDictionary;
|
||||
|
||||
#define ListDictionary_Object(_dictionary) (&_dictionary->object)
|
||||
#define ListDictionary_KeyObject(_dictionary) (&_dictionary->objectKey)
|
||||
#define ListDictionary_ValueObject(_dictionary) (&_dictionary->objectValue)
|
||||
|
||||
WINPR_API int ListDictionary_Count(wListDictionary* listDictionary);
|
||||
|
||||
WINPR_API void ListDictionary_Lock(wListDictionary* listDictionary);
|
||||
WINPR_API void ListDictionary_Unlock(wListDictionary* listDictionary);
|
||||
|
||||
WINPR_API void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value);
|
||||
WINPR_API BOOL ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value);
|
||||
WINPR_API void* ListDictionary_Remove(wListDictionary* listDictionary, void* key);
|
||||
WINPR_API void* ListDictionary_Remove_Head(wListDictionary* listDictionary);
|
||||
WINPR_API void ListDictionary_Clear(wListDictionary* listDictionary);
|
||||
|
@ -172,7 +172,7 @@ int ListDictionary_GetKeys(wListDictionary* listDictionary, ULONG_PTR** ppKeys)
|
||||
* Adds an entry with the specified key and value into the ListDictionary.
|
||||
*/
|
||||
|
||||
void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
|
||||
BOOL ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
|
||||
{
|
||||
wListDictionaryItem* item;
|
||||
wListDictionaryItem* lastItem;
|
||||
@ -181,6 +181,8 @@ void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
|
||||
EnterCriticalSection(&listDictionary->lock);
|
||||
|
||||
item = (wListDictionaryItem*) malloc(sizeof(wListDictionaryItem));
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
item->key = key;
|
||||
item->value = value;
|
||||
@ -203,6 +205,7 @@ void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
|
||||
|
||||
if (listDictionary->synchronized)
|
||||
LeaveCriticalSection(&listDictionary->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,8 +227,8 @@ void ListDictionary_Clear(wListDictionary* listDictionary)
|
||||
while (item)
|
||||
{
|
||||
nextItem = item->next;
|
||||
if (listDictionary->object.fnObjectFree)
|
||||
listDictionary->object.fnObjectFree(item->value);
|
||||
if (listDictionary->objectValue.fnObjectFree)
|
||||
listDictionary->objectValue.fnObjectFree(item->value);
|
||||
free(item);
|
||||
item = nextItem;
|
||||
}
|
||||
@ -243,31 +246,27 @@ void ListDictionary_Clear(wListDictionary* listDictionary)
|
||||
|
||||
BOOL ListDictionary_Contains(wListDictionary* listDictionary, void* key)
|
||||
{
|
||||
BOOL status = FALSE;
|
||||
wListDictionaryItem* item;
|
||||
OBJECT_EQUALS_FN keyEquals;
|
||||
|
||||
if (listDictionary->synchronized)
|
||||
EnterCriticalSection(&listDictionary->lock);
|
||||
|
||||
if (listDictionary->head)
|
||||
keyEquals = listDictionary->objectKey.fnObjectEquals;
|
||||
item = listDictionary->head;
|
||||
|
||||
while (item)
|
||||
{
|
||||
item = listDictionary->head;
|
||||
if (keyEquals(item->key, key))
|
||||
break;
|
||||
|
||||
while (item)
|
||||
{
|
||||
if (item->key == key)
|
||||
break;
|
||||
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
status = (item) ? TRUE : FALSE;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
if (listDictionary->synchronized)
|
||||
LeaveCriticalSection(&listDictionary->lock);
|
||||
|
||||
return status;
|
||||
return (item) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -279,42 +278,31 @@ void* ListDictionary_Remove(wListDictionary* listDictionary, void* key)
|
||||
void* value = NULL;
|
||||
wListDictionaryItem* item;
|
||||
wListDictionaryItem* prevItem;
|
||||
OBJECT_EQUALS_FN keyEquals;
|
||||
|
||||
if (listDictionary->synchronized)
|
||||
EnterCriticalSection(&listDictionary->lock);
|
||||
|
||||
if (listDictionary->head)
|
||||
{
|
||||
item = listDictionary->head;
|
||||
keyEquals = listDictionary->objectKey.fnObjectEquals;
|
||||
|
||||
if (listDictionary->head->key == key)
|
||||
item = listDictionary->head;
|
||||
prevItem = NULL;
|
||||
|
||||
while (item)
|
||||
{
|
||||
if (keyEquals(item->key, key))
|
||||
{
|
||||
listDictionary->head = listDictionary->head->next;
|
||||
if (!prevItem)
|
||||
listDictionary->head = item->next;
|
||||
else
|
||||
prevItem->next = item->next;
|
||||
value = item->value;
|
||||
free(item);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item->next)
|
||||
{
|
||||
prevItem = item;
|
||||
item = item->next;
|
||||
|
||||
while (item)
|
||||
{
|
||||
if (item->key == key)
|
||||
{
|
||||
prevItem->next = item->next;
|
||||
value = item->value;
|
||||
free(item);
|
||||
break;
|
||||
}
|
||||
|
||||
prevItem = item;
|
||||
item = item->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
prevItem = item;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
if (listDictionary->synchronized)
|
||||
@ -356,17 +344,20 @@ void* ListDictionary_GetItemValue(wListDictionary* listDictionary, void* key)
|
||||
{
|
||||
void* value = NULL;
|
||||
wListDictionaryItem* item = NULL;
|
||||
OBJECT_EQUALS_FN keyEquals;
|
||||
|
||||
if (listDictionary->synchronized)
|
||||
EnterCriticalSection(&listDictionary->lock);
|
||||
|
||||
keyEquals = listDictionary->objectKey.fnObjectEquals;
|
||||
|
||||
if (listDictionary->head)
|
||||
{
|
||||
item = listDictionary->head;
|
||||
|
||||
while (item)
|
||||
{
|
||||
if (item->key == key)
|
||||
if (keyEquals(item->key, key))
|
||||
break;
|
||||
|
||||
item = item->next;
|
||||
@ -389,24 +380,30 @@ BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, void* key, voi
|
||||
{
|
||||
BOOL status = FALSE;
|
||||
wListDictionaryItem* item;
|
||||
OBJECT_EQUALS_FN keyEquals;
|
||||
|
||||
if (listDictionary->synchronized)
|
||||
EnterCriticalSection(&listDictionary->lock);
|
||||
|
||||
keyEquals = listDictionary->objectKey.fnObjectEquals;
|
||||
if (listDictionary->head)
|
||||
{
|
||||
item = listDictionary->head;
|
||||
|
||||
while (item)
|
||||
{
|
||||
if (item->key == key)
|
||||
if (keyEquals(item->key, key))
|
||||
break;
|
||||
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
if (item)
|
||||
{
|
||||
if (listDictionary->objectValue.fnObjectFree)
|
||||
listDictionary->objectValue.fnObjectFree(item->value);
|
||||
item->value = value;
|
||||
}
|
||||
|
||||
status = (item) ? TRUE : FALSE;
|
||||
}
|
||||
@ -417,6 +414,10 @@ BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, void* key, voi
|
||||
return status;
|
||||
}
|
||||
|
||||
static BOOL default_equal_function(void *obj1, void *obj2)
|
||||
{
|
||||
return (obj1 == obj2);
|
||||
}
|
||||
/**
|
||||
* Construction, Destruction
|
||||
*/
|
||||
@ -425,19 +426,20 @@ wListDictionary* ListDictionary_New(BOOL synchronized)
|
||||
{
|
||||
wListDictionary* listDictionary = NULL;
|
||||
|
||||
listDictionary = (wListDictionary*) malloc(sizeof(wListDictionary));
|
||||
listDictionary = (wListDictionary*) calloc(1, sizeof(wListDictionary));
|
||||
if (!listDictionary)
|
||||
return NULL;
|
||||
|
||||
if (listDictionary)
|
||||
listDictionary->synchronized = synchronized;
|
||||
|
||||
if (!InitializeCriticalSectionAndSpinCount(&listDictionary->lock, 4000))
|
||||
{
|
||||
listDictionary->synchronized = synchronized;
|
||||
|
||||
listDictionary->head = NULL;
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&listDictionary->lock, 4000);
|
||||
|
||||
ZeroMemory(&(listDictionary->object), sizeof(wObject));
|
||||
free(listDictionary);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listDictionary->objectKey.fnObjectEquals = default_equal_function;
|
||||
listDictionary->objectValue.fnObjectEquals = default_equal_function;
|
||||
return listDictionary;
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,15 @@
|
||||
|
||||
int Queue_Count(wQueue* queue)
|
||||
{
|
||||
return queue->size;
|
||||
int ret;
|
||||
if (queue->synchronized)
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
ret = queue->size;
|
||||
|
||||
if (queue->synchronized)
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,7 +122,7 @@ BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
|
||||
for (index = 0; index < queue->tail; index++)
|
||||
{
|
||||
if (queue->array[index] == obj)
|
||||
if (queue->object.fnObjectEquals(queue->array[index], obj))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
@ -131,8 +139,10 @@ BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
* Adds an object to the end of the Queue.
|
||||
*/
|
||||
|
||||
void Queue_Enqueue(wQueue* queue, void* obj)
|
||||
BOOL Queue_Enqueue(wQueue* queue, void* obj)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (queue->synchronized)
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
@ -140,12 +150,20 @@ void Queue_Enqueue(wQueue* queue, void* obj)
|
||||
{
|
||||
int old_capacity;
|
||||
int new_capacity;
|
||||
void **newArray;
|
||||
|
||||
old_capacity = queue->capacity;
|
||||
new_capacity = queue->capacity * queue->growthFactor;
|
||||
|
||||
newArray = (void **)realloc(queue->array, sizeof(void*) * new_capacity);
|
||||
if (!newArray)
|
||||
{
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
queue->capacity = new_capacity;
|
||||
queue->array = (void**) realloc(queue->array, sizeof(void*) * queue->capacity);
|
||||
queue->array = newArray;
|
||||
ZeroMemory(&(queue->array[old_capacity]), old_capacity * sizeof(void*));
|
||||
|
||||
if (queue->tail < old_capacity)
|
||||
@ -161,8 +179,10 @@ void Queue_Enqueue(wQueue* queue, void* obj)
|
||||
|
||||
SetEvent(queue->event);
|
||||
|
||||
out:
|
||||
if (queue->synchronized)
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,6 +233,11 @@ void* Queue_Peek(wQueue* queue)
|
||||
return obj;
|
||||
}
|
||||
|
||||
static BOOL default_queue_equals(void *obj1, void *obj2)
|
||||
{
|
||||
return (obj1 == obj2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction, Destruction
|
||||
*/
|
||||
@ -240,13 +265,18 @@ wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor)
|
||||
if (!queue->array)
|
||||
goto out_free;
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&queue->lock, 4000);
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!queue->event)
|
||||
goto out_free_array;
|
||||
|
||||
if (!InitializeCriticalSectionAndSpinCount(&queue->lock, 4000))
|
||||
goto out_free_event;
|
||||
|
||||
queue->object.fnObjectEquals = default_queue_equals;
|
||||
return queue;
|
||||
|
||||
out_free_event:
|
||||
CloseHandle(queue->event);
|
||||
out_free_array:
|
||||
free(queue->array);
|
||||
out_free:
|
||||
@ -256,6 +286,9 @@ out_free:
|
||||
|
||||
void Queue_Free(wQueue* queue)
|
||||
{
|
||||
if (!queue)
|
||||
return;
|
||||
|
||||
Queue_Clear(queue);
|
||||
|
||||
CloseHandle(queue->event);
|
||||
|
@ -38,12 +38,17 @@
|
||||
|
||||
int Stack_Count(wStack* stack)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (stack->synchronized)
|
||||
{
|
||||
EnterCriticalSection(&stack->lock);
|
||||
|
||||
}
|
||||
ret = stack->size;
|
||||
|
||||
return 0;
|
||||
if (stack->synchronized)
|
||||
LeaveCriticalSection(&stack->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,7 +70,23 @@ BOOL Stack_IsSynchronized(wStack* stack)
|
||||
|
||||
void Stack_Clear(wStack* stack)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (stack->synchronized)
|
||||
EnterCriticalSection(&stack->lock);
|
||||
|
||||
for (index = 0; index < stack->size; index++)
|
||||
{
|
||||
if (stack->object.fnObjectFree)
|
||||
stack->object.fnObjectFree(stack->array[index]);
|
||||
|
||||
stack->array[index] = NULL;
|
||||
}
|
||||
|
||||
stack->size = 0;
|
||||
|
||||
if (stack->synchronized)
|
||||
LeaveCriticalSection(&stack->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,7 +95,25 @@ void Stack_Clear(wStack* stack)
|
||||
|
||||
BOOL Stack_Contains(wStack* stack, void* obj)
|
||||
{
|
||||
return FALSE;
|
||||
int i;
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (stack->synchronized)
|
||||
EnterCriticalSection(&stack->lock);
|
||||
|
||||
for (i = 0; i < stack->size; i++)
|
||||
{
|
||||
if (stack->object.fnObjectEquals(stack->array[i], obj))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stack->synchronized)
|
||||
LeaveCriticalSection(&stack->lock);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,6 +177,12 @@ void* Stack_Peek(wStack* stack)
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
static BOOL default_stack_equals(void *obj1, void *obj2)
|
||||
{
|
||||
return (obj1 == obj2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction, Destruction
|
||||
*/
|
||||
@ -146,26 +191,33 @@ wStack* Stack_New(BOOL synchronized)
|
||||
{
|
||||
wStack* stack = NULL;
|
||||
|
||||
stack = (wStack*) malloc(sizeof(wStack));
|
||||
stack = (wStack *)calloc(1, sizeof(wStack));
|
||||
if (!stack)
|
||||
return NULL;
|
||||
|
||||
if (stack)
|
||||
{
|
||||
stack->synchronized = synchronized;
|
||||
stack->object.fnObjectEquals = default_stack_equals;
|
||||
stack->synchronized = synchronized;
|
||||
|
||||
if (stack->synchronized)
|
||||
InitializeCriticalSectionAndSpinCount(&stack->lock, 4000);
|
||||
stack->capacity = 32;
|
||||
stack->array = (void**) malloc(sizeof(void*) * stack->capacity);
|
||||
if (!stack->array)
|
||||
goto out_free;
|
||||
|
||||
stack->size = 0;
|
||||
stack->capacity = 32;
|
||||
stack->array = (void**) malloc(sizeof(void*) * stack->capacity);
|
||||
}
|
||||
if (stack->synchronized && !InitializeCriticalSectionAndSpinCount(&stack->lock, 4000))
|
||||
goto out_free_array;
|
||||
|
||||
return stack;
|
||||
|
||||
out_free_array:
|
||||
free(stack->array);
|
||||
out_free:
|
||||
free(stack);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Stack_Free(wStack* stack)
|
||||
{
|
||||
if (stack)
|
||||
if (!stack)
|
||||
{
|
||||
if (stack->synchronized)
|
||||
DeleteCriticalSection(&stack->lock);
|
||||
|
Loading…
Reference in New Issue
Block a user