Back to my SIGTSTP handler. Its basic operation is thus: 0. start 1. block SIGTSTP 2. stop the watcher, returning SIGTSTP to default handling 3. send a SIGTSTP to self 4. unblock SIGTSTP, thus letting the pending SIGTSTP be delivered 5. after the process resumes, restart the watcher 6. end
I'm concerned about what happens if another SIGTSTP is delivered before the signal handler blocks it (stage 1 above). As things stand at the moment, in that case another SIGTSTP event gets queued. After the handler finishes and returns to the event loop, the second SIGTSTP event gets queued, and the process suspends itself again. What I'd like is for such a signal to be silently absorbed by the handler, just as is any SIGTSTP sent between stages 1 and 4 above. (A SIGTSTP between stages 4 and 5 suspends the process again immediately, which is correct behaviour. A SIGTSTP after stage 5 queues an event and causes another suspension by reinvoking the handler, which is also correct.) My ideal solution here would be a method to cancel a pending event. Since that doesn't exist, I coded a substitute that looks for a pending event and remembers its "hits" count; if the handler is invoked with an event whose hits counter matches the remembered value, then this means it's being invoked for a signal that we want to absorb, so it returns without doing anything. However, this doesn't work, because the "pending" method doesn't show a pending event even when a signal has been received. I see from the source that the signals received are first counted in a table, and the event objects are created later by pe_signal_asynccheck(), which is called from sweep() and one_event(). It looks to me as though ->pending() should also be doing the asynccheck thing. As a possible refinement, ->pending() on a signal watcher should be calling pe_signal_asynccheck(), and ->pending() on anything that's created an asynccheck hook should call that hook. I don't see any other methods that should be doing an asynccheck but aren't. In summary, then, two issues: 0. (bug) ->pending() should do an asynccheck 1. (wishlist) a "cancel" method on event objects would be nice And now you get some respite from me, because I'm going on holiday tomorrow. Back Monday evening (UK time). -zefram