httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ben Laurie <>
Subject Re: Apache 2.0 brokenness...
Date Sun, 23 Jan 2000 01:10:31 GMT
Ben Laurie wrote:
> The two children c1 and c2 start in this state:
> c1: blocked on the mutex (and hence not scheduling threads)
> c2: blocked on accept
> A connection comes in, which c2 accepts, c2 then releases the accept
> mutex and dispatches a second thread to handle the request. It then
> acquires the mutex again. By this point c1 has unblocked on the mutex
> because c2 released it, so c2 now blocks. Of course this disables the
> thread handling the connection, so nothing is returned to the browser.
> Until the next incoming connection, which causes c1 to release the
> mutex, so c2 unblocks the connection-handling thread (for a while at
> least).
> For doubting Thomases, here's the relevant manual snippet:
>      In the threaded library, the fcntl syscall is assembled to
>      _thread_sys_fcntl() and fcntl() is implemented as a function which
> dis-
>      ables thread rescheduling, locks fd for read and write, then calls
>      _thread_sys_fcntl().  Before returning, fcntl() unlocks fd and
> enables
>      thread rescheduling.
> Of course, this is a disaster and means that fcntl() simply cannot be
> used as a mutex in a threaded system (at least not this kind). As you
> say, flock() also behaves in the same way, and therefore also cannot be
> used.
> The interesting question is ... is there a way to test for systems that
> behave in this way? And, what do we use instead?

Well, I've poked at this quite a lot, and I have some answers...

a) You can use semaphores, if your system has them. FreeBSD does. I'll
be committing that soon. It appears to work.

b) The above passage would suggest that the smart thing to do would be
to call _thread_sys_fcntl() directly and _not_ disable thread
rescheduling (wtf do they do that, anyway?) but I can't find any
reference to that function in the headers. Does anyone know what this is
all about?

c) It _is_ possible to test for this condition. I can't quite be
bothered to write the code right now (its 1 AM), but here's pseudocode -
feel free to implement it if so inclined:

1. open a file
2. fork two children
3. each child spawns two threads
4. in each child, thread 1 takes out a write lock on the file and sleeps
5. thread 2 sleeps for 5 seconds and terminates the process (note that
in one child this will not wake up if you have the problem)
6. the parent sleeps for 10 seconds, then attempts to reap the two
7. if one of the children fails to reap, you have the problem

d) It ought to be possible to know whether serialised accepts are
required (or a good/bad idea), but I can only imagine that this has to
be based simply on knowing what the particular OS likes, requiring a
mechanism similar to the old Configure. Does anyone know different?




"My grandfather once told me that there are two kinds of people: those
who work and those who take the credit. He told me to try to be in the
first group; there was less competition there."
     - Indira Gandhi

View raw message