Currently, _cygtls::sigmask is set in call_signal_handler(), but this
is too late to effectively prevent a masked signal from being armed.
With this patch, deltamask, which is set in _cygtls::interrupt_setup()
in advancem, is also checked as well as sigmask to determine that the
signal can be armed.
Fixes: 0d675c5d7f24 ("* exceptions.cc (interrupt_setup): Don't set signal mask
here or races occur with main thread. Set it in sigdelayed instead.")
Reviewed-by:
Signed-off-by: Takashi Yano <[email protected]>
---
winsup/cygwin/exceptions.cc | 6 +++++-
winsup/cygwin/mm/cygheap.cc | 13 +++++++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index bcc7fe6f8..a4699b172 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1322,6 +1322,7 @@ set_process_mask_delta ()
else
oldmask = _my_tls.sigmask;
newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE;
+ _my_tls.deltamask = 0;
sigproc_printf ("oldmask %lx, newmask %lx, deltamask %lx", oldmask, newmask,
_my_tls.deltamask);
_my_tls.sigmask = newmask;
@@ -1544,12 +1545,15 @@ sigpacket::process ()
if (tl_entry)
{
tls = tl_entry->thread;
+ tl_entry->thread->lock ();
if (sigismember (&tls->sigwait_mask, si.si_signo))
issig_wait = true;
- else if (!sigismember (&tls->sigmask, si.si_signo))
+ else if (!sigismember (&tls->sigmask, si.si_signo)
+ && !sigismember (&tls->deltamask, si.si_signo))
issig_wait = false;
else
tls = NULL;
+ tl_entry->thread->unlock ();
}
}
diff --git a/winsup/cygwin/mm/cygheap.cc b/winsup/cygwin/mm/cygheap.cc
index 4cc851716..338886468 100644
--- a/winsup/cygwin/mm/cygheap.cc
+++ b/winsup/cygwin/mm/cygheap.cc
@@ -743,6 +743,7 @@ init_cygheap::find_tls (int sig, bool& issig_wait)
while (++ix < (int) nthreads)
{
/* Only pthreads have tid set to non-0. */
+ threadlist[ix].thread->lock ();
if (!threadlist[ix].thread->tid
|| !threadlist[ix].thread->initialized)
;
@@ -752,13 +753,21 @@ init_cygheap::find_tls (int sig, bool& issig_wait)
issig_wait = true;
break;
}
- else if (!t && !sigismember (&(threadlist[ix].thread->sigmask), sig))
+ else if (!t && !sigismember (&(threadlist[ix].thread->sigmask), sig)
+ && !sigismember (&(threadlist[ix].thread->deltamask), sig))
+ {
t = &cygheap->threadlist[ix];
+ break;
+ }
+ threadlist[ix].thread->unlock ();
}
/* Leave with locked mutex. The calling function is responsible for
unlocking the mutex. */
if (t)
- WaitForSingleObject (t->mutex, INFINITE);
+ {
+ threadlist[ix].thread->unlock ();
+ WaitForSingleObject (t->mutex, INFINITE);
+ }
return t;
}
--
2.45.1