apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <...@covalent.net>
Subject Re: Possible race condition in pools WAS: RE: Thoughts on locks
Date Wed, 27 Jun 2001 15:16:56 GMT

This is correct.  Most of the locking in pools was based on the fact that
Apache doesn't have this type of problem.  We can either fix the problem
with code or docs, but it does need to be fixed.

Ryan

On Wed, 27 Jun 2001, Brian Pane wrote:

> 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
> >
> >
>
>
>
>


_____________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
Covalent Technologies			rbb@covalent.net
-----------------------------------------------------------------------------


Mime
View raw message