apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jacob Lewallen <jlewa...@cs.ucr.edu>
Subject [PATCH] apr_queue race condition
Date Sun, 09 Feb 2003 21:28:13 GMT
   Hi there, I've stumbled on a bug in the apr_queue_t code... When 
calling apr_queue_pop to retrieve an item from the queue the call may 
block indefinately despite items having been pushed in. Same things goes 
for calls to apr_queue_push that are blocking until there is room in the 
queue (they may stay blocked even though items have been popped from the 
queue). The problem lies in the logic that manages the two conditions 
that help operate the queue - NOT_EMPTY, and NOT_FULL. In 
apr_queue_push, the NOT_EMPTY condition is only signaled if the queue 
was empty prior to adding the new item. This can cause problems if there 
are multiple threads blocked in calls to apr_queue_pop and then two or 
more successive calls to apr_queue_push are handled prior to one of the 
apr_queue_pop awakening... for example:

apr_queue_pop1 [BLOCKED] (nelts = 0)
apr_queue_pop2 [BLOCKED] (nelts = 0)
apr_queue_pop3 [BLOCKED] (nelts = 0)
apr_queue_push1 (nelts = 1) (nelts was 0, so signals)
apr_queue_push2 (nelts = 2)
apr_queue_pop1 [UNBLOCKS] (nelts = 1) (awake from push1's signal)
apr_queue_push3 (nelts = 2)
apr_queue_push4 (nelts = 3)

pop2, pop3 as well as any others remained blocked.

Similar logic is used to handle blocked calls to apr_queue_push. My 
solution was to add two variables to apr_queue_t to track the number of 
threads waiting for a non-full and non-empty state, and choosing to 
signal the conditions based on those variables. So far this has worked 
fine for me. testqueue doesn't seem to catch this because of the way 
it's written (timing delays betwee calls make this harder to catch)

I've attached a patch. I appreciate any comments, it being my first 
patch and all.

jacob lewallen

View raw message