On Sun, Jan 13, 2008 at 06:55:58AM +0100, Marc Lehmann wrote: > On Sat, Jan 12, 2008 at 11:51:04AM -0500, Chris Shoemaker <[EMAIL PROTECTED]> > wrote: > > Actually, ev_child is not usable by rubinius because it eagerly consumes > > all child exit statuses, even before an ev_child has been started. > > That is untrue. It only does that when the default event loop is running, > when you are in a watcher or outside any ev_loop call libev will do no > such thing.
Yes, I did mean "when the default event loop is running". I do want to use the default event loop for ev_signals. > > You could argue that it's the application's responsibility to catch > > every ev_child event and store the exit status indefinitely just in > > case it might need it in the future. > > An event-based app doesn't block and poll for the exist status of > processes, it registers handlers for them. Right. I'm neither blocking nor polling. See below. > > However, this is very complicated and requires complex locking between > > the reader and writer (the ev_child handler) of the data store for > > eagerly-consumed exit statuses. > > As I explained, if for whatever reason it is inconvinient to use it, > don't. Libev doesn't force the use of its child watcher. Well, it doesn't force the use of ev_child, but it does force an application to choose between either: a) not having access to the exit status of children that exited before a ev_child was started, OR b) not being able to use ev_signal I'd like to use ev_signal (for unrelated purposes, mostly) AND have access to exit status of children that exited before I knew I would want their exit status, (for which I know I need to use my old SIGCHLD handler, that I used with libevent). > > > I do not think so: the default loop is for use by all components in a > > > program. If you need a loop without signal handling, just create one. > > > > Actually, rubinius wants to use the default loop for ev_signal. > > But ev_signal has the same problem: As soon as some part of a program > registers a watcher, signal handlers instaleld via sigaction stop working. I don't follow. I don't intend to use sigaction. I want to use ev_signal for all signal watching. > > > The problem with disabling is, what should libev do when asked to provide > > > a > > > child watcher? abort? > > > > How about treating it exactly as if the loop didn't support ev_child, > > just like every non-default loop? > > That would mean a crash. I don't think that this is acceptable, as one of > the basic premises of the default loop is to support all those features. Well, I would think that aborting if the application attempted to use a feature that it explicitly disabled would be acceptable. However, another option could be to offer another loop type: Something just like the default loop but without the SIGCHLD handler. > > Sure, a non-default loop would avoid the sigchld handler, but prevents > > me from using ev_signal. :( > > Other factors would, too, as signal handlers are unsharable, just like > waiting for child exist statuses is unsharable. You'd only postpone the > problem. I don't follow. What problem would I postpone? > > I would very much like to get rid of my sigchld handler, but it has an > > important property that I need: it does not consume the exit status of > > any processes unless it has been explicitly asked to. > > How does it do so? Looping over all pid's on all calls to sigchld? Thats > extremely inefficient... No indeed. That's not only inefficient, it's also insufficient because I can't get the process group of the child after it has terminated, but I would need the process group in order to know whether the child matched the criteria that I'm interested in (in case of e.g. pid < -1 argument to waitpid). Instead, I loop over only list of outstanding calls to waitpid, passing only the pid arguments that I'm interested in receiving child statuses for. Thus, I never receive a child status before I am ready to consume it, so I never have to store them anywhere. As for efficiency, this makes the SIGCHLD handler O(N) in the number outstanding waitpid calls. I don't expect that to be a problem, but I'm open to suggestions for improvement. [ After writing this, I took a look at how ev_childs are handled, and realized that it would be quite easy to modify libev to provide the behavior I want. I would just remove the waitpid(-1) call, and put a waitpid(pid) call inside the loop over childs[]. As an added benefit, ev_child would then also support pid < -1 arguments, with the semantics of waitpid(). I will very likely do exactly that, and I'll send a patch if you're interested. ] > > On another note... I'm having problems with unreliable signal > > delivery after a fork - with poll, select and epoll backends. > > What is "unreliable signal delivery"? libev doesn't do anything to signals > after a fork, so whatever you see is probably normal (POSIX) behaviour or > some bug. I'm sorry for being unclear. I only meant that, after a fork, signals sent to the child don't seem to be consistently triggering the ev_signals I would expect. I'll need to investigate this further. It's quite possibly a bug somewhere in my application code. -chris _______________________________________________ libev mailing list [email protected] http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
