After the commit d243e51ef1d3, zsh sometimes hangs at startup. This is because SIGCHLD is handled in cygwait() for a wakeup event even when __SIGFLUSHFAST is sent, despite __SIGFLUSHFAST requiring to return before handling the signal. With this patch, if the signal sent is __SIGFLUSHFAST, do not handle the arrived signal and keep it being asserted after the cygwait() for the wakeup event.
Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256954.html Fixes: d243e51ef1d3 ("Cygwin: signal: Fix deadlock between main thread and sig thread") Reported-by: Daisuke Fujimura <booleanla...@gmail.com> Reviewed-by: Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp> --- winsup/cygwin/release/3.5.6 | 5 +++++ winsup/cygwin/sigproc.cc | 14 ++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 winsup/cygwin/release/3.5.6 diff --git a/winsup/cygwin/release/3.5.6 b/winsup/cygwin/release/3.5.6 new file mode 100644 index 000000000..643d58e58 --- /dev/null +++ b/winsup/cygwin/release/3.5.6 @@ -0,0 +1,5 @@ +Fixes: +------ + +- Fix zsh hang at startup. + Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256954.html diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index ba7818a68..d676799cc 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -785,7 +785,16 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) if (wait_for_completion) { sigproc_printf ("Waiting for pack.wakeup %p", pack.wakeup); - rc = cygwait (pack.wakeup, WSSC); + do + { + rc = cygwait (pack.wakeup, WSSC, cw_sig_eintr); + if (rc == WAIT_SIGNALED && pack.si.si_signo != __SIGFLUSHFAST) + _my_tls.call_signal_handler (); + } + while (rc != WAIT_OBJECT_0 && rc != WAIT_TIMEOUT); + /* Re-assert signal_arrived which has been cleared in cygwait(). */ + if (_my_tls.current_sig) + _my_tls.set_signal_arrived (); ForceCloseHandle (pack.wakeup); } else @@ -806,9 +815,6 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) rc = -1; } - if (wait_for_completion && si.si_signo != __SIGFLUSHFAST) - _my_tls.call_signal_handler (); - out: if (communing && rc) { -- 2.45.1