https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=364226a4caaa277d86fcc0c58ef862cb23a50603

commit 364226a4caaa277d86fcc0c58ef862cb23a50603
Author: Takashi Yano <takashi.y...@nifty.ne.jp>
Date:   Sat Jun 7 17:00:35 2025 +0900

    Cygwin: signal: Enable the signal mask earlier
    
    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 advance, is also checked as well as sigmask to determine if 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: Corinna Vinschen <cori...@vinschen.de>
    Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp>

Diff:
---
 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;
 }

Reply via email to