SIGCHLD not received
Denis Bilenko
denis.bilenko at gmail.com
Wed May 30 12:55:52 CEST 2012
On Wed, May 30, 2012 at 1:29 AM, Marc Lehmann <schmorp at schmorp.de> wrote:
> On Tue, May 29, 2012 at 10:57:31PM +0400, Denis Bilenko <denis.bilenko at gmail.com> wrote:
>> No, it's not that. Attached is the program that checks the error codes
>> and also waits for a child using child watcher. Still fails.
>
> Now you changed your program considerably, and I am too lazy/sleepy to
> track down further bugs in it.
Don't worry - I don't feel entitled to your time just because I use
your (free) software. I actually appreciate you taking time to reply
here (and to release libev in the first place - thanks!).
> If I modify your original program in the way I said, to close the extra
> fd, call waitpid on the child and destroy the default loop before the next
> fork, it runs fine here.
Yes, it seems that waitpid() somehow masks or avoids the bug. If I
apply this small patch to your program it fails - why? Wouldn't
ev_run() take care of waiting for the child for me the same way as the
removed waitpid() did?
--- testsigchld_marc_orig.c 2012-05-30 14:23:52.904252701 +0400
+++ testsigchld_marc.c 2012-05-30 14:20:08.263154490 +0400
@@ -55,12 +55,14 @@
alarm(5);
struct ev_io io;
+ struct ev_child child;
ev_io_init(&io, stop_io, pipefd[0], 1);
ev_io_start(ev_default_loop(0), &io);
+ ev_child_init(&child, stop_child, pid, 0);
+ ev_child_start(ev_default_loop(0), &child);
ev_run(ev_default_loop(0), 0);
ev_loop_destroy (EV_DEFAULT);
close(pipefd[0]);
- waitpid(pid, 0, 0);//D
alarm(0);
}
> You could use that as starting point, although my recommendations from my
> first reply are still something you should consider seriously :)
The recommendations are good - I have found empirically too that
fork+exec is just more reliable than fork when you use libev loop in
the parent. However, this particular test program is extracted from
python-gevent test suite, not a real application. I cannot change it
much, except to fix bugs in libev usage, like call ev_loop_fork() when
needed (which original Python program already did - it was lost during
translation to C). BTW, the original test case did not have an
infinite loop, it just failed randomly, which suggests that the
failure may happen on the first iteration.
My solution so far has been to add a timer reaping the children
periodically (attached). But I still have no idea what makes SIGCHLD
being skipped in the first place.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: libev_childpollev.patch
Type: application/octet-stream
Size: 2526 bytes
Desc: not available
URL: <http://lists.schmorp.de/pipermail/libev/attachments/20120530/616c16ca/attachment.obj>
More information about the libev
mailing list