> From: Corinna Vinschen [corinna-cygwin@cygwin.com] > Sent: Wednesday, October 21, 2015 4:48 AM > Subject: Re: pthread_kill: signals remain pending after target thread exits ... > > 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. ... > The important thing here is to get rid of the pending signal. Yes, I agree that is the most important thing. > > 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? I've attached a test case that I *think* gets into the right spot, at least for 64-bit Cygwin 2.0.4. That is, it hangs trying to receive the signal, instead of terminating. (This test passes (terminates) in 32-bit Cygwin 1.7.9 and 64-bit Ubuntu 14.04.3 LTS.) As to a fix: sorry, but though I looked at the code, I am not sufficiently confident to suggest a specific change. I think that the internal signal handling thread has exclusive access to the pending signal collection, which is one difficulty. And I'm not sure how the race is resolved between something trying to use the cygtls and the cygtls being destroyed. At a guess, there are at least two general approaches to a fix: 1. Somehow prevent new signals from being sent to the terminating thread, then notify the internal signal handling thread of the need to purge pending signals targeting the doomed thread, then delay cygtls destruction until confirmation that that purge is complete. 2. In the pending signal representation, replace the direct cygtls address with a pointer to some small reference-counted object associated with the cygtls. That small object could live on for a while, even after the original cygtls has been destroyed and its memory reused for a new cygtls, so that the signal processing thread can take its time purging references. But there has to be some way to atomically do two things: 1) check whether this small object still points to a valid cygtls, and 2) if it does, delay destruction of that cygtls until some task has been performed (such as processing a signal). Perhaps this small object could contain an invalidation flag and some synchronization objects (mutex, condition variable, etc.) in addition to the raw cygtls pointer. > > - 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... Yeah. It's nice if threads don't interfere with each other, but this part would indeed be harder to change. -- John Carey