apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brian Pane <bp...@pacbell.net>
Subject Re: Possible race condition in pools WAS: RE: Thoughts on locks
Date Wed, 27 Jun 2001 08:34:04 GMT
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
>
>




Mime
View raw message