diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 3195d5719..60c1f594f 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1527,11 +1527,14 @@ sigpacket::process () if ((HANDLE) *tls) tls->signal_debugger (si); - if (issig_wait) + tls->lock (); + if (issig_wait && tls->sigwait_mask != 0) { tls->sigwait_mask = 0; + tls->unlock (); goto dosig; } + tls->unlock (); if (handler == SIG_IGN) { diff --git a/winsup/cygwin/release/3.5.5 b/winsup/cygwin/release/3.5.5 index b70b91ed8..d91f2b92c 100644 --- a/winsup/cygwin/release/3.5.5 +++ b/winsup/cygwin/release/3.5.5 @@ -42,3 +42,6 @@ Fixes: - Fix NtCreateEvent() error in create_lock_ob() called from flock(). Addresses: https://cygwin.com/pipermail/cygwin/2024-November/256750.html + +- Fix segfault in sigtimedwait() when using timeout. + Addresses: https://cygwin.com/pipermail/cygwin/2024-November/256762.html diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 77152910b..9ee6cf995 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -615,6 +615,7 @@ sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime) set_signal_mask (_my_tls.sigwait_mask, *set); sig_dispatch_pending (true); +do_wait: switch (cygwait (NULL, waittime, cw_sig_eintr | cw_cancel | cw_cancel_self)) { @@ -640,6 +641,17 @@ sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime) } break; case WAIT_TIMEOUT: + _my_tls.lock (); + if (_my_tls.sigwait_mask == 0) + { + /* sigpacket::process() already started. + Will surely be signalled soon. */ + waittime = cw_infinite; + _my_tls.unlock (); + goto do_wait; + } + _my_tls.sigwait_mask = 0; + _my_tls.unlock (); set_errno (EAGAIN); break; default: