Yes, there's definitely a race condition there. I noticed that too, and I thought it was intentional (i.e., that the lack of a lock was a conscious choice to avoid a performance penalty for apps in which pools aren't shared across threads) and harmless (because there aren't any pools in Apache shared by multiple threads that can do apr_palloc). But if the non-thread-safety is intentional, there probably should be a prominent warning about it in the include file and documentation. --Brian Sander Striker wrote: >[...] > >>In the current apr_palloc, the lock is only around the call to new_block. >>I think that's reasonable; new_block is manipulating a global >>free list, so it has to be mutex-protected. >> > >This triggered me to investigate the pools code again. It seems to me that >there is a possible race condition when two threads share the same pool. >Examine the following piece of code that is not protected by a lock: > > ... > new_first_avail = first_avail + size; > > if (new_first_avail <= blok->h.endp) { > debug_verify_filled(first_avail, blok->h.endp, > "[apr_palloc] Ouch! Someone trounced past the >end " > "of their allocation!\n"); > blok->h.first_avail = new_first_avail; > return (void *) first_avail; > } > ... > >Now in a situation with 2 threads that call apr_palloc at the same time >(both requesting a size that fits the last block): > > A B >T1 new_first_avail = first_avail + size; >T2 new_first_avail = first_avail + >size; > >Now, the test will succeed in both A and B, effectively returning the same >memory twice: > > if (new_first_avail <= blok->h.endp) { > blok->h.first_avail = new_first_avail; > return (void *) first_avail; > } > >Or am I missing something? > > >Sander > >