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.

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.

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().

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.

Thoughts?




Reply via email to