Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions threadpool_pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,19 @@ static void *threadpool_do_work(void *arg) {
pthread_exit(NULL);
}

static void threadpool_create_thread_on_demand(threadpool_s *threadpool) {
static bool threadpool_create_thread_on_demand(threadpool_s *threadpool) {
// Create new thread and add it to the list of threads
pthread_t handle = 0;
if (pthread_create(&handle, NULL, threadpool_do_work, threadpool))
return;
return false;

threadpool_thread_s *thread = (threadpool_thread_s *)calloc(1, sizeof(threadpool_thread_s));
thread->handle = handle;
thread->next = threadpool->threads;

threadpool->threads = thread;
threadpool->num_threads++;
return true;
Comment on lines 171 to +177
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function creates a pthread but doesn't check if the subsequent calloc fails. If calloc fails (thread is NULL), the code will dereference a NULL pointer on line 172. Additionally, if calloc fails after pthread_create succeeds, the created thread will be orphaned (memory leak) since the thread handle is not stored and cannot be joined later. Add a NULL check after calloc and if it fails, consider detaching the thread or implementing proper cleanup.

Copilot uses AI. Check for mistakes.
}

bool threadpool_enqueue(void *ctx, void *user_data, threadpool_job_cb callback) {
Expand All @@ -189,6 +190,12 @@ bool threadpool_enqueue(void *ctx, void *user_data, threadpool_job_cb callback)
// Add job to the job queue
threadpool_enqueue_job(threadpool, job);

// Create min amount of threads
while (threadpool->num_threads < threadpool->min_threads) {
if (!threadpool_create_thread_on_demand(threadpool))
break;
}
Comment on lines +193 to +197
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new functionality to ensure minimum threads are created lacks test coverage. Consider adding a test that verifies min_threads are actually created when jobs are enqueued, especially to prevent regression of this bug in the future.

Copilot uses AI. Check for mistakes.

// Create new thread if all threads are busy
if (threadpool->busy_threads == threadpool->num_threads && threadpool->num_threads < threadpool->max_threads)
threadpool_create_thread_on_demand(threadpool);
Comment on lines 200 to 201
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value of threadpool_create_thread_on_demand is ignored here. If thread creation fails at this point (when all threads are busy), the failure will be silent and the job may not be processed in a timely manner. Consider checking the return value and possibly logging a warning when thread creation fails.

Suggested change
if (threadpool->busy_threads == threadpool->num_threads && threadpool->num_threads < threadpool->max_threads)
threadpool_create_thread_on_demand(threadpool);
if (threadpool->busy_threads == threadpool->num_threads && threadpool->num_threads < threadpool->max_threads) {
if (!threadpool_create_thread_on_demand(threadpool)) {
fprintf(stderr, "threadpool: warning: failed to create thread on demand; job processing may be delayed\n");
}
}

Copilot uses AI. Check for mistakes.
Expand Down
Loading