apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "William A. Rowe, Jr." <wr...@rowe-clan.net>
Subject Re: challenges creating processes from threaded environment?
Date Sat, 24 May 2003 05:29:47 GMT
At 08:02 PM 5/23/2003, Jeff Trawick wrote:
>consider code that does something like the following:
>
>apr_procattr_io_set()
>/* we now have 6 pipe handles with no cleanup-for-exec on any */
>apr_proc_create()
>/* parent now has 3 of the pipe handles with no cleanup-for-exec on any */
>apr_pool_cleanup_register(parent handle to child's stdin,
>                          child cleanup to close file)
>/* now we know that other processes created between now and when we're through writing
to child's stdin won't inherit the handle too and prevent the child from seeing EOF when this
thread closes it */
>
>But this entire sequence needs to be in a critical section because any other code in the
process doing an apr_proc_create() at about the same time can inherit this child's handles
and cause problems.

100% correct.  I was looking at this a couple of weeks ago, but hadn't
formulated any obvious answers to it (without seriously throttling all
multithreaded apps.)

>I encountered this problem in Apache's mod_ext_filter, which spawns a child process to
filter a response from the server.  Banging on the server and having it spawn sed to filter
the response left a number of sed processes hanging around, all waiting for EOF on stdin.
 But each sed's stdin pipe was led open by another sed process, so it mattered not that Apache
had closed its side of the pipe since the pipe was still open.

OWWW!  That's a case I hadn't considered.  However, the right answer
is to close the children's side of the pipes, always.  If they are left open,
it's much harder to detect that the child has died/you've reached EOF.

>For mod_ext_filter I can hold a thread mutex around the critical section  above, and that
protects it from other instances of mod_ext_filter doing fork() and inheriting the wrong handle,
but it does nothing for other threads calling apr_proc_create().

The right answer, in part, is to close those child handles.  The second side
is to protect that window where we declare the handles as keep-open on
exec to the point where we've already fork()ed.

>It would seem that all of the pipe creation and child cleanup registration needs to be
done inside apr_proc_create() so that it can hold a mutex and all callers of apr_proc_create()
will be happy.  I didn't look at it to know if that would require API changes.  I wouldn't
be shocked.

For the small window between declaring the handles keep-open,
fork()ing the child and then closing them in the parent, we absolutely
need a mutex to keep things clean.

Otherwise, two children may have the write side of the parent's read pipe,
and when the first (real) child dies, we don't know it.

Bill



Mime
View raw message