static void *worker_thr_routine(void *data) { struct threadpool *pool = (struct threadpool*)data; struct threadpool_task *task; while (1) { task = threadpool_task_get_task(pool); if (task == NULL) { if (pool->stop_flag) { break; } else { DEMO_THREAD_Print("Warning an error has occurred when trying to obtain a worker task."); DEMO_THREAD_Print("The worker thread has exited."); break; } } if (task->routine_cb) { task->routine_cb(task->data); threadpool_task_init(task); if (pthread_mutex_lock(&(pool->free_tasks_mutex))) { perror("pthread_mutex_lock: "); DEMO_THREAD_Print("The worker thread has exited."); break; } if (threadpool_queue_enqueue(&(pool->free_tasks_queue),task)) { DEMO_THREAD_Print("Failed to enqueue a task to free tasks queue."); if (pthread_mutex_unlock(&(pool->free_tasks_mutex))) { perror("pthread_mutex_unlock: "); } DEMO_THREAD_Print("The worker thread has exited."); break; } if (threadpool_queue_getsize(&(pool->free_tasks_queue)) == 1) { if (pthread_cond_broadcast(&(pool->free_tasks_cond))) { perror("pthread_cond_broadcast: "); if (pthread_mutex_unlock(&(pool->free_tasks_mutex))) { perror("pthread_mutex_unlock: "); } break; } } if (pthread_mutex_unlock(&(pool->free_tasks_mutex))) { perror("pthread_mutex_unlock: "); DEMO_THREAD_Print("The worker thread has exited."); break; } } } return NULL; }
/** * This is the routine the worker threads do during their life. * * @param data Contains a pointer to the threadpool structure. * @return NULL. */ static void *worker_thr_routine(void *data) { struct threadpool *pool = (struct threadpool*)data; struct threadpool_task *task; while (1) { task = threadpool_task_get_task(pool); if (task == NULL) { if (pool->stop_flag) { /* Worker thr needs to exit (thread pool was shutdown). */ break; } else { /* An error has occurred. */ REPORT_ERROR("Warning an error has occurred when trying to obtain a worker task."); REPORT_ERROR("The worker thread has exited."); break; } } /* Execute routine (if any). */ if (task->routine_cb) { task->routine_cb(task->data); /* Release the task by returning it to the free_task_queue. */ threadpool_task_init(task); if (pthread_mutex_lock(&(pool->free_tasks_mutex))) { perror("pthread_mutex_lock: "); REPORT_ERROR("The worker thread has exited."); break; } if (threadpool_queue_enqueue(&(pool->free_tasks_queue),task)) { REPORT_ERROR("Failed to enqueue a task to free tasks queue."); if (pthread_mutex_unlock(&(pool->free_tasks_mutex))) { perror("pthread_mutex_unlock: "); } REPORT_ERROR("The worker thread has exited."); break; } if (threadpool_queue_getsize(&(pool->free_tasks_queue)) == 1) { /* Notify all waiting threads that new tasks can added. */ if (pthread_cond_broadcast(&(pool->free_tasks_cond))) { perror("pthread_cond_broadcast: "); if (pthread_mutex_unlock(&(pool->free_tasks_mutex))) { perror("pthread_mutex_unlock: "); } break; } } if (pthread_mutex_unlock(&(pool->free_tasks_mutex))) { perror("pthread_mutex_unlock: "); REPORT_ERROR("The worker thread has exited."); break; } } } return NULL; }