[newlib-cygwin/cygwin-3_6-branch] Cygwin: signal: Enable the signal mask earlier

Takashi Yano via Cygwin-cvs <[email protected]>
Newsgroups gmane.os.cygwin.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=b57c6c013bf0899d3b39048bfb7e46197a0a9689

commit b57c6c013bf0899d3b39048bfb7e46197a0a9689
Author: Takashi Yano <[email protected]>
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 <[email protected]>
    Signed-off-by: Takashi Yano <[email protected]>
    (cherry picked from commit 364226a4caaa277d86fcc0c58ef862cb23a50603)

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;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.