Skip to content

Instantly share code, notes, and snippets.

@denik
Created May 30, 2012 20:28
Show Gist options
  • Save denik/2838734 to your computer and use it in GitHub Desktop.
Save denik/2838734 to your computer and use it in GitHub Desktop.
bug in libev child watcher after fork
/* gcc -DEV_STANDALONE=1 testsigchld4.c -o testsigchld4
*
* Expected output: infinite sequence of "*."
*
* Actual output:
* denis@denis-laptop:~/work/libev-cvs$ ./testsigchld4
* Alarm clock
* (and the subprocess exits 60 seconds later).
*
* */
#include "ev.c"
void stop_child(struct ev_loop* loop, ev_child *w, int revents) {
ev_child_stop(loop, w);
}
int CHECK(int retcode) {
if (retcode < 0) {
perror("fail");
_exit(1);
}
return retcode;
}
void subprocess(void) {
int pid;
if (pid = CHECK(fork())) {
sleep(1);
struct ev_child child;
ev_child_init(&child, stop_child, pid, 0);
ev_child_start(EV_DEFAULT, &child);
ev_run(EV_DEFAULT, 0);
CHECK(fprintf(stderr, "*"));
}
else {
_exit(0);
}
}
void test_main(void) {
ev_default_loop(EVBACKEND_SELECT);
int pid = CHECK(fork());
if (!pid) {
ev_loop_fork(EV_DEFAULT);
// fix 1: replace ev_loop_fork with loop re-creation and it would work
//ev_loop_destroy(EV_DEFAULT);
//ev_default_loop(EVBACKEND_SELECT);
// fix 2:
// ev_run(EV_DEFAULT, 0);
subprocess();
_exit(0);
}
alarm(5);
waitpid(pid, 0, 0);
alarm(0);
ev_loop_destroy(EV_DEFAULT);
}
int main(int argc, char** argv) {
while (1) {
test_main();
CHECK(fprintf(stderr, "."));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment