Skip to content

Commit

Permalink
properly free threadpool if failed to create (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
hassanctech authored Dec 13, 2023
1 parent 1c4f6ec commit 2dc0a16
Showing 1 changed file with 12 additions and 16 deletions.
28 changes: 12 additions & 16 deletions src/utils/src/Threadpool.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ PVOID threadpoolActor(PVOID data)
}

// This actor will now wait for a task to be added to the queue, and then execute that task
// when the task is complete it will check if the we're beyond our min threshhold of threads
// when the task is complete it will check if the we're beyond our min threshold of threads
// to determine whether it should exit or wait for another task.
while (!finished) {
// This lock exists to protect the atomic increment after the terminate check.
Expand Down Expand Up @@ -171,18 +171,7 @@ STATUS threadpoolCreate(PThreadpool* ppThreadpool, UINT32 minThreads, UINT32 max

CleanUp:
if (STATUS_FAILED(retStatus)) {
if (mutexCreated) {
MUTEX_FREE(pThreadpool->listMutex);
}
if (listCreated) {
stackQueueFree(pThreadpool->threadList);
}
if (queueCreated) {
safeBlockingQueueFree(pThreadpool->taskQueue);
}
if (poolCreated) {
SAFE_MEMFREE(pThreadpool);
}
threadpoolFree(pThreadpool);
}
return retStatus;
}
Expand All @@ -195,7 +184,7 @@ STATUS threadpoolInternalCreateThread(PThreadpool pThreadpool)
{
STATUS retStatus = STATUS_SUCCESS;
PThreadData data = NULL;
BOOL locked = FALSE;
BOOL locked = FALSE, dataCreated = FALSE;
TID thread;
CHK(pThreadpool != NULL, STATUS_NULL_ARG);

Expand All @@ -206,6 +195,7 @@ STATUS threadpoolInternalCreateThread(PThreadpool pThreadpool)

data = (PThreadData) MEMCALLOC(1, SIZEOF(ThreadData));
CHK(data != NULL, STATUS_NOT_ENOUGH_MEMORY);
dataCreated = TRUE;

data->dataMutex = MUTEX_CREATE(FALSE);
data->pThreadpool = pThreadpool;
Expand All @@ -216,14 +206,20 @@ STATUS threadpoolInternalCreateThread(PThreadpool pThreadpool)
MUTEX_UNLOCK(pThreadpool->listMutex);
locked = FALSE;

THREAD_CREATE(&thread, threadpoolActor, data);
THREAD_DETACH(thread);
CHK_STATUS(THREAD_CREATE(&thread, threadpoolActor, data));
CHK_STATUS(THREAD_DETACH(thread));

CleanUp:
if (locked) {
MUTEX_UNLOCK(pThreadpool->listMutex);
}

// If logic changes such that it's possible successfully enqueue data but not create the thread
// We may attempt a double free. Right now it's fine.
if (STATUS_FAILED(retStatus) && dataCreated) {
SAFE_MEMFREE(data);
}

return retStatus;
}

Expand Down

0 comments on commit 2dc0a16

Please sign in to comment.