in src/tp_worker_thread.c [140:174]
static void tp_worker_on_threadpool_work(void* context)
{
if (context == NULL)
{
/*Codes_SRS_TP_WORKER_THREAD_42_037: [ If context is NULL then tp_worker_on_threadpool_work shall terminate the process. ]*/
LogCriticalAndTerminate("Invalid args: void* context = %p", context);
}
else
{
TP_WORKER_THREAD_HANDLE worker_thread = context;
do
{
/*Codes_SRS_TP_WORKER_THREAD_42_038: [ tp_worker_on_threadpool_work shall call worker_func with worker_func_context. ]*/
worker_thread->worker_func(worker_thread->worker_func_context);
/*Codes_SRS_TP_WORKER_THREAD_42_039: [ If the state is EXECUTING then tp_worker_on_threadpool_work shall change the state to IDLE and return. ]*/
if (interlocked_compare_exchange(&worker_thread->processing_state, WORKER_THREAD_STATE_IDLE, WORKER_THREAD_STATE_EXECUTING) == WORKER_THREAD_STATE_EXECUTING)
{
// IDLE now, just break, next schedule process call will start a new threadpool work thread
wake_by_address_all(&worker_thread->processing_state);
break;
}
/*Codes_SRS_TP_WORKER_THREAD_42_040: [ If the state is SCHEDULE_REQUESTED then tp_worker_on_threadpool_work shall change the state to EXECUTING and repeat. ]*/
int32_t current_processing_state = interlocked_compare_exchange(&worker_thread->processing_state, WORKER_THREAD_STATE_EXECUTING, WORKER_THREAD_STATE_SCHEDULE_REQUESTED);
if (current_processing_state == WORKER_THREAD_STATE_SCHEDULE_REQUESTED)
{
// have to keep executing
wake_by_address_all(&worker_thread->processing_state);
continue;
}
} while (true);
}
}