proposal: defer installing SIGCHLD

Marc Lehmann schmorp at
Fri May 25 11:42:14 CEST 2012

On Thu, May 24, 2012 at 07:40:27PM +0400, Denis Bilenko <denis.bilenko at> wrote:
> > behavious is deterministic right now - when you want to do your own signal
> > handling, you e.g. block/ev_default_loop/restore/unblock, and that is much
> > harder (if possible at all) to do otherwise.
> It's not much harder if you really want to do it that way. Just start
> a dummy child watcher after initializing the loop - that will trigger
> the signal handler installation. However, you should not need to do
> it. Instead, just don't use child watchers.

Right, but it's unnecessary complication nevertheless.

> My point is that the mere presence of "ev_child_start()" call in your
> code declares the intent of using libev's child reaping over any
> other.

ev_child_start signifies the desire to get child notifications. I doubt a
program cares how it's implemented a slong as it works.

> If you don't have ev_child_start() in your code, then libev
> won't install a signal handler so there's no need for specific order
> of init calls or for undoing SIGCHLD installation.

That can already be done by disabling child watchers when compiling
libev. libev will not tinker with SIGCHLD in that case.

If child watchers are not disabled then it's effectively impossible to know
whether it will be called in the future or not, and then libev needs to
install a child watcher.

> I cannot imagine a case where someone would disable libev's child
> reaping and then proceeds to use child watchers.

Right, if libev's child reaping is *disabled* then you can't use child
watchers, because the necessary functions aren't even defined.

> Can any one give me a non-hypothetical example of this?

No, because it'S nonsensical. I can give you a real world example of where
somebody wnats to take over child reaping over libev - the example you gave,
when you want to keep ev_child functionality working inside libev but let the
child reaping be done by another library or piece of code, for whatever

In this acse, one library has to give, and libev cna either feed child
events to the other library, or some code needs to feed it to libev.

> I know you can feed events to a watcher, but if you're only feeding
> events to a watcher, you no longer care which type of watcher it is, so
> use any other than child.

Well, I do care which watcher I feed events to, so what you say is already
wrong. I think in general when you feed events to a watcher you do care
very much about that watcher.

> Here's a more important case: the libev's libevent emulation.
> Currently, it reaps children, which makes it incompatible with
> libevent programs that have their own child management.

libev is also incompatible with programs that define their own
ev_child_start function.

libevent emulation doesn't mean that libev only implements libevent
interfaces and nothing else, it means it implements libevent interfaces
(but also libev interfaces).

> With the patch
> it all works out naturally - the libevent-only program will never call

Your patch implements a race condition and makes child weatchers unreliable
(i.e. they will never be called sometimes). To fix your patch you'd have to
add extra checking code.

Your patch also breaks *existing* libev programs. Your patch doesn't help any
existing programs that work with libevent and libev.

As such, this argument is rather weak - your patch would cause a lot more
breakage than it would be helpful for.

> I guess you can fix it following your own advice: make event_init() do
> block/ev_default_loop/restore/unblock dance.

In most cases you you only have to order things right, first initialise the
default loop, then install your handler, as opposed to the other way round.

So making it work requires zero overhead in typical cases.

> However, if you defer signal installation it just works - no
> workarounds necessary.

Well, it obviously doesn't work - the child handler must be in place
before ev_child_start is called (specifically, it must be called before

> The new loop option would not help me unless there is also a function
> to start child reaping at any time.

That would also cause a race condition, causing *the other* event library to
lose child signals.

It is unfortunate that unix is designed as it is w.r.t. signals, but I
think libev makes it pretty easy to work around these limitations while
maintaining maximum efficiency.

As has been explained before, you have yet to make an actually workign
proposal for what you want to achieve. Your patch, as has been pointed out
to you before, simply doesn't work at all.

So before talking about pros and cons of some hypothetical solution
and breaking backwards compatibility, we first would need to have an
indication that a solution is even possible.

The only known solution is what's implemented by libev at the moment.

                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_    
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      schmorp at
      -=====/_/_//_/\_,_/ /_/\_\

More information about the libev mailing list