I have a rather simple thread pool, and i have a question regarding thread finalizing.
this is my worker snippet :
static void* threadpool_worker(void* pool_instance)
{
int rc;
struct threadpool* pool = (struct threadpool*)pool_instance;
struct threadpool_task *task;
for(;;)
{
pthread_mutex_lock( &(pool->task_queue_mutex) );
while( pool->headp->tqh_first == NULL )
{
rc = pthread_cond_wait( &(pool->task_queue_cond), &(pool->task_queue_mutex) );
}
task = pool->headp->tqh_first;
TAILQ_REMOVE(pool->headp, pool->headp->tqh_first, entries);
pthread_mutex_unlock( &(pool->task_queue_mutex) );
task->routine_cb(task->data);
}
}
so jobs are executed at this line task->routine_cb(task->data);
and in order to finalize workers threads i'm calling threadpool_enqueue_task
in the following way :
for( i=0 ; i < pool->num_of_workers ; ++i)
{
threadpool_enqueue_task(pool, pthread_exit, NULL);
}
expecting that pthread_exit will be called in here task->routine_cb(task->data) but it does not work this way, i don't see any explicit error, just memory leak in valgrind
but when i change the worker code like that :
if(task->routine_cb == pthread_exit)
{
pthread_exit(0);
}
task->routine_cb(task->data);
everything ends fine. so my question is is there an option to stop the worker just making it to execute pthread_exit in some way,without changing the worker code.
Edit: Thread pool task declared as following :
struct threadpool_task
{
void (*routine_cb)(void*);
void *data;
TAILQ_ENTRY(threadpool_task) entries; /* List. */
}
As per my understanig there should be no problem to get address of pthread_exit in routine_cb which declared :
extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__));