Commit 6ecfc962 authored by Denis Bilenko's avatar Denis Bilenko

save&undo libev's SICHLD handler when installed; install it when first child...

save&undo libev's SICHLD handler when installed; install it when first child is created or when install_sigchld() is called
parent b0d6eeb0
......@@ -244,7 +244,7 @@ cdef public class loop [object PyGeventLoopObject, type PyGeventLoop_Type]:
if _default_loop_destroyed:
default = False
if default:
self._ptr = libev.ev_default_loop(c_flags)
self._ptr = libev.gevent_ev_default_loop(c_flags)
if not self._ptr:
raise SystemError("ev_default_loop(%s) failed" % (c_flags, ))
libev.ev_prepare_start(self._ptr, &self._signal_checker)
......@@ -421,6 +421,9 @@ cdef public class loop [object PyGeventLoopObject, type PyGeventLoop_Type]:
def child(self, int pid, bint trace=0, ref=True):
return child(self, pid, trace, ref)
def install_sigchld(self):
libev.gevent_install_sigchld_handler()
#endif
def stat(self, bytes path, float interval=0.0, ref=True, priority=None):
......@@ -851,6 +854,7 @@ cdef public class child(watcher) [object PyGeventChildObject, type PyGeventChild
def __init__(self, loop loop, int pid, bint trace=0, ref=True):
if not loop.default:
raise TypeError('child watchers are only available on the default loop')
libev.gevent_install_sigchld_handler()
libev.ev_child_init(&self._watcher, <void *>gevent_callback_child, pid, trace)
self.loop = loop
if ref:
......
......@@ -2,4 +2,43 @@
#include "ev.c"
#else
#include "ev.h"
#if EV_CHILD_ENABLE
#include <signal.h>
#endif
#endif
#if EV_CHILD_ENABLE
static struct sigaction libev_sigchld;
static int sigchld_state = 0;
static struct ev_loop* gevent_ev_default_loop(unsigned int flags)
{
if (sigchld_state)
return ev_default_loop(flags);
struct ev_loop* result;
struct sigaction tmp;
sigaction(SIGCHLD, NULL, &tmp);
result = ev_default_loop(flags);
// XXX what if SIGCHLD received there?
sigaction(SIGCHLD, &tmp, &libev_sigchld);
sigchld_state = 1;
return result;
}
static void gevent_install_sigchld_handler(void) {
if (sigchld_state == 1) {
sigaction(SIGCHLD, &libev_sigchld, NULL);
sigchld_state = 2;
}
}
#else
#define gevent_ev_default_loop ev_default_loop
static void gevent_install_sigchld_handler(void) { }
#endif
......@@ -185,3 +185,6 @@ cdef extern from "libev.h":
void ev_unref(ev_loop*)
void ev_break(ev_loop*, int)
unsigned int ev_pending_count(ev_loop*)
ev_loop* gevent_ev_default_loop(unsigned int flags)
void gevent_install_sigchld_handler()
......@@ -598,6 +598,8 @@ class Popen(object):
if executable is None:
executable = args[0]
self._loop.install_sigchld()
# For transferring possible exec failure from child to parent
# The first char specifies the exception type: 0 means
# OSError, 1 means some other error.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment