Bug 49709 - apr_thread_pool_push may fail to wake up a thread in the thread pool
Summary: apr_thread_pool_push may fail to wake up a thread in the thread pool
Status: RESOLVED FIXED
Alias: None
Product: APR
Classification: Unclassified
Component: APR-util (show other bugs)
Version: HEAD
Hardware: All All
: P2 major (vote)
Target Milestone: ---
Assignee: Apache Portable Runtime bugs mailinglist
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-08-05 08:24 UTC by Joe Mudd
Modified: 2010-09-28 06:41 UTC (History)
0 users



Attachments
apr_thread_pool.c patch (2.93 KB, text/plain)
2010-08-05 08:24 UTC, Joe Mudd
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Joe Mudd 2010-08-05 08:24:37 UTC
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.
Comment 1 Jeff Trawick 2010-09-28 06:41:04 UTC
Thanks for the patch!
Fixed in 1.3.x branch through trunk...