On Thu, Sep 29, 2011 at 05:45:46PM +0200, Jörg F. Wittenberger wrote: > Here an interesting finding: > > On Sep 29 2011, Alan Post wrote: > > >This patch replaces signal with sigaction for registering signals. > >sigaction is a newer API for signal processing that fixes some > >deficiencies of the original signal API. One fix can be seen in > >this patch: we don't have to reregister the signal handler after > >a signal is sent. > > > >That prevents a race condition whereby a signal is delivered, our > >signal handler is reset, and before we can reregister our signal > >handler, another signal is sent (which we then miss). > > Since I'm quite old school I've been used to the meaning of signals > to be "almost reliable". Except under arbitrary complex usage > restrictions. > > Hence I rarely ever tried to count signals, but use them as a hint, > which operation would be in order. > > This might have been not enough! > > Turn out that with your patch applied something changed: > I had one usage case, which "almost sure" (say ~50%+-25%) would run > into that eat-all-memory condition. I tried too often, I fail to > reproduce the condition. > > However at this time I can't convince myself that this is not a false > positive. :-/ >
Even with my patch, there is still a bug in the chicken signal handler: void global_signal_handler(int signum) { C_raise_interrupt(signal_mapping_table[ signum ]); } This signal handler will notify the main thread that signal X has been raised, but it doesn't keep track of how often that happens. By the time we get around to handling this signal, it could have been raised more than once, and we only fire our signal handler once regardless of how many signals were delivered between the original interrupt and executing the deferred handler. If you're doing anything at all that is reasonably interrupt heavy, you're going to be seeing this behavior. The quick test would be to fork a few hundred children (that all immediately exit) all at once and count the number of times SIGCHLD is raised. I haven't written this test yet, it's my next test case to follow my EINTR test--though I suspect you'll get fewer SIGCHLD interrupts than you had spawned children. I also suspect there is a condition here where the signal handler flags the interrupt to be raised, but we're already servicing the deferred signal, and it goes ahead and resets the signal_mapping_table before the signal currently being raised is handled by deferral. If you're coping with unreliable delivery from the above method, maybe you're seeing this case instead, which would be a different class of behavior. Rather than 1 or more deferred signals being delivered for N signals raised, you might well see 0 under this condition--If this can happen at all. I'm assuming it can, looking at the code, but haven't verified yet. -Alan -- .i ma'a lo bradi cu penmi gi'e du _______________________________________________ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users