Skip to content

Commit 33799c2

Browse files
tyan0jeremyd2019
authored andcommitted
Cygwin: signal: Do not handle signal when __SIGFLUSHFAST is sent
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/[email protected] 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 <[email protected]> Reviewed-by: Signed-off-by: Takashi Yano <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 985e265 commit 33799c2

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

winsup/cygwin/release/3.5.6

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Fixes:
2+
------
3+
4+
- Fix zsh hang at startup.
5+
Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256954.html

winsup/cygwin/sigproc.cc

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -751,10 +751,14 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
751751
res = WriteFile (sendsig, leader, packsize, &nb, NULL);
752752
if (!res || packsize == nb)
753753
break;
754-
if (cygwait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED)
754+
if (cygwait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED
755+
&& pack.si.si_signo != __SIGFLUSHFAST)
755756
_my_tls.call_signal_handler ();
756757
res = 0;
757758
}
759+
/* Re-assert signal_arrived which has been cleared in cygwait(). */
760+
if (_my_tls.sig)
761+
_my_tls.set_signal_arrived ();
758762

759763
if (!res)
760764
{
@@ -785,7 +789,16 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
785789
if (wait_for_completion)
786790
{
787791
sigproc_printf ("Waiting for pack.wakeup %p", pack.wakeup);
788-
rc = cygwait (pack.wakeup, WSSC);
792+
do
793+
{
794+
rc = cygwait (pack.wakeup, WSSC, cw_sig_eintr);
795+
if (rc == WAIT_SIGNALED && pack.si.si_signo != __SIGFLUSHFAST)
796+
_my_tls.call_signal_handler ();
797+
}
798+
while (rc != WAIT_OBJECT_0 && rc != WAIT_TIMEOUT);
799+
/* Re-assert signal_arrived which has been cleared in cygwait(). */
800+
if (_my_tls.sig)
801+
_my_tls.set_signal_arrived ();
789802
ForceCloseHandle (pack.wakeup);
790803
}
791804
else
@@ -806,9 +819,6 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
806819
rc = -1;
807820
}
808821

809-
if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
810-
_my_tls.call_signal_handler ();
811-
812822
out:
813823
if (communing && rc)
814824
{

0 commit comments

Comments
 (0)