static void tp_worker_on_threadpool_work()

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);
    }
}