Hi John, On Sep 11 18:11, John Carey wrote: > There seems to be a problem with pthread_kill: a pending signal > targeting a particular thread prevents other threads from receiving > signals sharing the same signal number--even after the original target > thread exits and is joined. > > To reproduce the issue: > > 1. Block signal number S. > > 2. Create thread T. > > 3. Send a signal with signal number S to thread T in particular (as > opposed to the process in general). > > 4. After that signal has been sent, allow T to terminate without > unblocking S or calling sigwait(). > > 5. Join T. > > 6. Create thread N. > > 7. Have N call sigwait() with a signal set that contains S. > > 8. Send to N a new signal with signal number S. > > 9. N never receives the new signal--instead, the new signal is > discarded because the earlier signal remains pending. Yuk. > BUT: It seems possible that N might inadvertently inherit the pending > signal if its _cygtls instance happens to be allocated at the same > address as the _cygtls instance of T. It would be hard to predict > when that would happen. See the discussion of the source code, below. The important thing here is to get rid of the pending signal. > For comparison, note that when performing the same steps on Linux > (Ubuntu 14.04.3), N does in fact receive the second signal. > > Here is the relevant Cygwin source code, if I am understanding things > correctly: > > - sigproc.cc : wait_sig : calls pending_signals::add, then tries to > process signals in the queue, but leaves queued any signal that > failed to process > > - exceptions.cc : sigpacket::process : signal processing fails if it > cannot find the target thread using init_cygheap::find_tls > > - sigproc.cc : pending_signals::add : discards new signals whose > signal number matches that of a pending signal--regardless of target > thread > > - cygheap.cc : init_cygheap::find_tls : looks for a thread by the > address of its _cygtls instance, but a thread that has been joined > might happen to have had the same _cygtls address as a thread that > was subsequently created, and therefore pending signals for > terminated threads might sometimes be inherited by unrelated new > threads (or so it seems to me--as yet I have not managed to trigger > such a scenario) > > In my view it would be desirable if: > > - Pending signals targeting a particular thread would not outlast > that thread. Since you looked into the code anyway, do you have an idea how to implement that? For a start, do you have a simple testcase, only the bare code needed to reproduce the issue? > - Multiple pending signals targeting different threads could > coexist, even if they shared the same signal number. This happens > on Linux (Ubuntu 14.04.3), where I can generate two signals for two > different threads, then sleep for a bit in each target thread, and > finally have each thread receive its signal with sigwait()--neither > signal is lost during the sleeping period. That requires to extend the handling for pending signals. That's a rather bigger task... Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Maintainer cygwin AT cygwin DOT com Red Hat