On 18/02/07, Shachar Shemesh <[EMAIL PROTECTED]> wrote:
Baruch Even wrote: > You want to avoid another case of race condition. > I think Amos intended to simply call "exit" from the signal handler, so that problem would not be an issue. However:
Indeed.
Without a select you will have code like: > > handle_sigchld() { dead_child=1; wait(); } > dorecv() { > if (!dead_child) { > recv(); > } > } > > The problem now can be that the 'if (!dead_child)' is executed, then the > signal comes and then the recv() is executed since we already thought > that the child is alive.
So how long should the select timeout be? Arbitrary?
An even better solution, and one that does not include neither races nor timeouts is to use "poll(2)" instead of "recv". Poll has an option for changing the signal mask for the duration of the syscall. In a nutshell, you would block SIGCHLD, and then call "poll" to find out if a message arrived, while also enabling SIGCHLD for the duration of the syscall. RTFM on poll for more info.
Since: 1. Using connection-based sockets should pretty reliably avoid this entire issue - they won't be there when the other side is dead. 2. With double-forking daemons SIGCHLD will be pretty redundant - the parent will still need to stay around and find another way to know when to quit. I think I can just ignore the problem - maybe setup a child reaper just to clean the direct child's zombie but generally just wait for recv to signal socketpair closure. Thanks, --Amos