Re: libev's child reaping breaks system() function

2010-08-26 Thread Marc Lehmann
On Thu, Aug 26, 2010 at 08:02:17PM +0200, Robin Haberkorn  
wrote:
> However in multi-threaded environments, system() cannot

multi-threading itself breaks a lot of stuff (fork for example) in subtle
ways. this issue is not really something that libev can do something
about.

the solution is to not use system then, just as any other funciton that
causes problems when threading.

> That doesn't seem to be pretty much straight-forward.
> IMHO, I could live without the ev_child watcher at all but
> I would be happy with a clean way to use ev_signal to process
> SIGCHLDs.

Don't use system or multihreading - posix is harsh, and multithreading
imposes rather draconic limitations on a program. not much that can be
doen about it. it's a pain in the ass, but libev can only use what posix
offers.

-- 
The choice of a   Deliantra, the free code+content MORPG
  -==- _GNU_  http://www.deliantra.net
  ==-- _   generation
  ---==---(_)__  __   __  Marc Lehmann
  --==---/ / _ \/ // /\ \/ /  schm...@schmorp.de
  -=/_/_//_/\_,_/ /_/\_\

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


libev's child reaping breaks system() function

2010-08-26 Thread Robin Haberkorn
Hi!

I don't know if that has been brought up before (I couldn't
find anything). libev reaps all child processess synchronously
in the default event loop. This behaviour can result in child
reaping race conditions, generally if waitpid() and in
particular if system() (declared in stdlib.h) is also used in
the program.
In single-threaded programs, this shouldn't cause any problem
because of the synchronous reaping. Even if children would
be reaped asynchronously, system() would block (mask out)
SIGCHLD temporarily.
However in multi-threaded environments, system() cannot
mask out SIGCHLD for every thread. I'm currently investigating
whether this is ok or a bug in itself. At least it happens with
both uClibc and glibc which use a similar system()
implementation (which call sigprocmask() for masking out
SIGCHLD...).
Of course it would be possible to reset the signal handler
after default loop initialization, but what if you still want
to use events for child reaping purposes? It would still be
possible to reap only the children you're actually interested
in or synchronize the waitpid() and system() calls with a
mutex. Unfortunately it doesn't seem to be possible to
use an ev_signal for SIGCHLDs, maybe because libev uses an
ev_signal for child reaping internally!?
So the only way to not break the system() (and waitpid())
calls in a multi-threaded environment seems to be using
an async watcher. In pseudo-code:

ev_default_init(0);
ev_async_init(&async, async_cb);
ev_async_start(EV_DEFAULT_UC_ &async);
signal(SIGCHLD, chld_hnd);
...
void chld_hnd(int s) {
ev_async_send(EV_DEFAULT_UC_ &async);
}
...
void async_cb(EV_P_ ev_async *w, int revents) {
// do whatever we would have done in an ev_signal handler
}

That doesn't seem to be pretty much straight-forward.
IMHO, I could live without the ev_child watcher at all but
I would be happy with a clean way to use ev_signal to process
SIGCHLDs.

cheers,
Robin

-- 
-- 
-- managed broadband access --

Travelping GmbH   phone:   +49-391-8190990
Roentgenstr. 13   fax:   +49-391-819099299
D-39108 Magdeburg email:   i...@travelping.com
GERMANY   web:   http://www.travelping.com


Company Registration: Amtsgericht Stendal Reg No.:   HRB 10578
Geschaeftsfuehrer: Holger Winkelmann | VAT ID No.: DE236673780
--

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev