Hacker News new | ask | show | jobs
by listeria 321 days ago
This is the first I've heard of using an open pipe to poll for subprocess termination. Don't get me wrong, I don't hate it, but you could just as easily have a SIGCHLD handler write to your pipe (or do nothing, since poll(2) will be fail with EINTR), and you don't have to worry about the subprocess closing the pipe or considering it some weird stddata fd like tree does here.
2 comments

`SIGCHLD` is extremely unreliable in a lot of ways, `pidfd` is better (but Linux-specific), though it doesn't handle the case of wanting to be notified of all grandchildren's terminations after the direct child dies early.
In what ways is it unreliable? You're notified when a child is stopped, terminated, or continued, and you can make it so that you're only notified of termination using SA_NOCLDSTOP.

How is `pidfd` better, why would you use it instead of a SIGCHLD handler writing to a pipe?

Imagine you are a library, that needs to fork (and exec, of course) some children processes to do its work. Since you're a library, you can't just set a SIGCHLD handler (for instance, the main application could have set SA_NOCLDWAIT for itself, and let's not even get into the question of which thread will actually receive the signals). Polling waitid(2) for each of them would require a separate thread per child process, unless you can put all of your children, current and future, into a single separate process group — which you normally can't. I guess you could try to use a single thread to do waitid(2) with WNOWAIT for all children processes and filter out only those you're interested in... but you probably will keep getting the one you're not interested in over and over again, until the main thread will reap it. There are some improvements to this I can think of, but honestly, all the traditional waitXXX(2) functions simply are not properly composable.
This is actually a well known technique, often called the self-pipe trick. There’s a good overview in the following SO answer from Rich Felker, muslc’s author:

https://stackoverflow.com/questions/3703013/what-can-cause-e...

The technique described in the SO answer doesn't really apply here, since the write end of the pipe would be closed on exec in that case. Whereas in this case they're waiting for it to be closed after the child dies.
Sure, it may not apply in this specific case. But you said “This is the first I've heard of using an open pipe to poll for subprocess termination” and I was just pointing out that this is a well known technique.