Skip to content

Commit

Permalink
Cygwin: signal: Do not handle signal when __SIGFLUSHFAST is sent
Browse files Browse the repository at this point in the history
After the commit d243e51, zsh sometimes hangs at startup. This
occurs because SIGCHLD, which should trigger sigsuspend(), is handled
in cygwait() that is used to wait for a wakeup event in sig_send(),
even when __SIGFLUSHFAST is sent. Despite __SIGFLUSHFAST being
required to return before handling the signal, this does not happen.
With this patch, if the signal currently being sent is __SIGFLUSHFAST,
do not handle the received signal and keep it asserted after the
cygwait() for the wakeup event.  Apply the same logic to the cygwait()
in the retrying loop for WriteFile() as well.

Applied-from: https://inbox.sourceware.org/cygwin-patches/20241223013332.1269-1-takashi.yano@nifty.ne.jp
Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256954.html
Fixes: d243e51 ("Cygwin: signal: Fix deadlock between main thread and sig thread")
Reported-by: Daisuke Fujimura <booleanlabel@gmail.com>
Reviewed-by:
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
tyan0 authored and jeremyd2019 committed Dec 25, 2024
1 parent 985e265 commit 33799c2
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
5 changes: 5 additions & 0 deletions winsup/cygwin/release/3.5.6
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Fixes:
------

- Fix zsh hang at startup.
Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256954.html
20 changes: 15 additions & 5 deletions winsup/cygwin/sigproc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -751,10 +751,14 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
res = WriteFile (sendsig, leader, packsize, &nb, NULL);
if (!res || packsize == nb)
break;
if (cygwait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED)
if (cygwait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED
&& pack.si.si_signo != __SIGFLUSHFAST)
_my_tls.call_signal_handler ();
res = 0;
}
/* Re-assert signal_arrived which has been cleared in cygwait(). */
if (_my_tls.sig)
_my_tls.set_signal_arrived ();

if (!res)
{
Expand Down Expand Up @@ -785,7 +789,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.sig)
_my_tls.set_signal_arrived ();
ForceCloseHandle (pack.wakeup);
}
else
Expand All @@ -806,9 +819,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)
{
Expand Down

0 comments on commit 33799c2

Please sign in to comment.