Re: GChildWatch source -- take two



Thus spake Jonathan Blandford:
> "Alexis S. L. Carvalho" <alexis cecm usp br> writes:
> 
> > The fact that you can only install the signal handler after launching a
> > child still feels sort of like using uninitialized data.  I don't see
> > where this could be a problem, but then, I'm no Unix guru...
> 
> The only problem I came up with was when the user already has a child
> handler that calls wait() or waitpid(-1), and the child exits before the
> new handler is installed.  I wonder if we should special case
> g_child_watch_add (-1|0); and add a return value to GChildWatchFunc so
> that the handler can be canceled.

If you mean special casing -1|0 so that it just installs the signal
handler, it may be better to just make g_child_watch_init public to
avoid magical values.  This should avoid this kind of race.

It'd probably be pretty hard to safely uninstall the handler - either
the programmer or GLib would have to guarantee that there are no
GChildWatchSources pending.

Oh, speaking of initialization functions, I think
g_child_watch_source_init is not safe against two threads calling
g_child_watch_source_new for the first time at the same time.

> > I don't think this has to be volatile.
> 
> It wasn't originally.  I just put it in to make Alex feel better. (-;

I think he meant the global child_watch_count that is modified in
the signal handler.

> > Now the bad news:  I'm afraid I wasn't able to run your child-test
> > correctly.  I don't really know the internals of GMainLoop, but if I
> > understood correctly, it was always the thread running in main that
> > called waitpid.  It always failed with ECHILD (No child processes).
> 
> I may have sent a bogus copy of child-test.c in retrospect.  Let me
> attach another copy instead.

Same problem: the thread that calls waitpid is the one that runs in the
function main, and because of bugs in LinuxThreads it can't wait for the
children of the other threads.

This one is going to be pretty hard (if not impossible) to fix in the
general case:  if a thread runs a child and then exits before the child,
the child is reparented to init and no SIGCHLD is delivered.

In the not-so-general case, it may be worth noting that the SIGCHLD is
delivered to the thread that launched the child process.

Alexis, waiting for NPTL to become widespread.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]