Created attachment 25844 [details] apr_thread_pool.c patch I have observed the following race condition between add_task() and thread_pool_func(). If thread_pool_func() owns the me->lock and determines that there is no more work in the task list, the thread will insert itself on the idle list then it will enter wait. Before entering wait, thread_pool_func() releases me->lock then attempts to acquire conditional related me->cond_lock. If add_task() is blocked on me->lock while thread_pool_func() is placing itself on the idle list, add_task() may acquire me->lock as soon as thread_pool_func() releases it. When add_task() is able to beat the single thread pool thread in thread_pool_func() in its acquisition of the conditional related me->cond_lock, we end up with work in the thread pool and no awake threads to process the work. Depending on the application, this may cause an infinite wait for the work to complete. The attached patch changes all condition activity to make use of the main data structure lock (me->lock) instead of the conditional lock (me->cond_lock). That way the addition of work and waking a thread becomes an atomic operation. As well as the placement of a thread in the idle list and waiting for more work.
Thanks for the patch! Fixed in 1.3.x branch through trunk...