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

Reply via email to