diff --git a/msys2-runtime/0056-fixup-Cygwin-signal-Do-not-handle-signal-when-__SIGF.patch b/msys2-runtime/0056-fixup-Cygwin-signal-Do-not-handle-signal-when-__SIGF.patch new file mode 100644 index 00000000000..dc16a50fee1 --- /dev/null +++ b/msys2-runtime/0056-fixup-Cygwin-signal-Do-not-handle-signal-when-__SIGF.patch @@ -0,0 +1,75 @@ +From 7ad033fa4834dae3c44a6baeaa6a697c080bc5d2 Mon Sep 17 00:00:00 2001 +From: Takashi Yano +Date: Tue, 21 Jan 2025 12:15:33 +0900 +Subject: [PATCH 56/N] fixup! Cygwin: signal: Do not handle signal when + __SIGFLUSHFAST is sent + +This reverts commit a22a0ad7c4f0 to apply a new patch for the same +purpose. + +Signed-off-by: Takashi Yano +--- + winsup/cygwin/release/3.5.6 | 5 ----- + winsup/cygwin/sigproc.cc | 20 +++++--------------- + 2 files changed, 5 insertions(+), 20 deletions(-) + delete mode 100644 winsup/cygwin/release/3.5.6 + +diff --git a/winsup/cygwin/release/3.5.6 b/winsup/cygwin/release/3.5.6 +deleted file mode 100644 +index 643d58e..0000000 +--- a/winsup/cygwin/release/3.5.6 ++++ /dev/null +@@ -1,5 +0,0 @@ +-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 c298527..cf43aa9 100644 +--- a/winsup/cygwin/sigproc.cc ++++ b/winsup/cygwin/sigproc.cc +@@ -751,14 +751,10 @@ 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 +- && pack.si.si_signo != __SIGFLUSHFAST) ++ if (cygwait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED) + _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) + { +@@ -789,16 +785,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) + if (wait_for_completion) + { + sigproc_printf ("Waiting for pack.wakeup %p", pack.wakeup); +- 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 (); ++ rc = cygwait (pack.wakeup, WSSC); + ForceCloseHandle (pack.wakeup); + } + else +@@ -819,6 +806,9 @@ 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) + { diff --git a/msys2-runtime/0057-Cygwin-cygwait-Make-cygwait-reentrant.patch b/msys2-runtime/0057-Cygwin-cygwait-Make-cygwait-reentrant.patch new file mode 100644 index 00000000000..4c017838858 --- /dev/null +++ b/msys2-runtime/0057-Cygwin-cygwait-Make-cygwait-reentrant.patch @@ -0,0 +1,143 @@ +From 28e4e5594d8f838c39dd307b08e5e7d2d577bc97 Mon Sep 17 00:00:00 2001 +From: Takashi Yano +Date: Mon, 20 Jan 2025 23:54:56 +0900 +Subject: [PATCH 57/N] Cygwin: cygwait: Make cygwait() reentrant + +To allow cygwait() to be called in the signal handler, a locally +created timer is used instead of _cygtls::locals.cw_timer if it is +in use. + +Co-Authored-By: Corinna Vinschen +Signed-off-by: Takashi Yano +(cherry picked from commit ea1914000adcbed5c16fc0ba2676173b2f6016c4) +--- + winsup/cygwin/cygtls.cc | 2 ++ + winsup/cygwin/cygwait.cc | 22 +++++++++++++++------- + winsup/cygwin/local_includes/cygtls.h | 3 ++- + winsup/cygwin/select.cc | 10 +++++++++- + 4 files changed, 28 insertions(+), 9 deletions(-) + +diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc +index afaee8e..b8b5a01 100644 +--- a/winsup/cygwin/cygtls.cc ++++ b/winsup/cygwin/cygtls.cc +@@ -64,6 +64,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *)) + initialized = CYGTLS_INITIALIZED; + errno_addr = &(local_clib._errno); + locals.cw_timer = NULL; ++ locals.cw_timer_inuse = false; + locals.pathbufs.clear (); + + if ((void *) func == (void *) cygthread::stub +@@ -85,6 +86,7 @@ _cygtls::fixup_after_fork () + signal_arrived = NULL; + locals.select.sockevt = NULL; + locals.cw_timer = NULL; ++ locals.cw_timer_inuse = false; + locals.pathbufs.clear (); + wq.thread_ev = NULL; + } +diff --git a/winsup/cygwin/cygwait.cc b/winsup/cygwin/cygwait.cc +index dbbe1db..bb653f6 100644 +--- a/winsup/cygwin/cygwait.cc ++++ b/winsup/cygwin/cygwait.cc +@@ -58,16 +58,20 @@ cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) + } + + DWORD timeout_n; ++ HANDLE local_timer = NULL; ++ HANDLE &wait_timer = ++ _my_tls.locals.cw_timer_inuse ? local_timer : _my_tls.locals.cw_timer; + if (!timeout) + timeout_n = WAIT_TIMEOUT + 1; + else + { ++ if (!_my_tls.locals.cw_timer_inuse) ++ _my_tls.locals.cw_timer_inuse = true; + timeout_n = WAIT_OBJECT_0 + num++; +- if (!_my_tls.locals.cw_timer) +- NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL, +- NotificationTimer); +- NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL); +- wait_objects[timeout_n] = _my_tls.locals.cw_timer; ++ if (!wait_timer) ++ NtCreateTimer (&wait_timer, TIMER_ALL_ACCESS, NULL, NotificationTimer); ++ NtSetTimer (wait_timer, timeout, NULL, NULL, FALSE, 0, NULL); ++ wait_objects[timeout_n] = wait_timer; + } + + while (1) +@@ -100,7 +104,7 @@ cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) + { + TIMER_BASIC_INFORMATION tbi; + +- NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi, ++ NtQueryTimer (wait_timer, TimerBasicInformation, &tbi, + sizeof tbi, NULL); + /* if timer expired, TimeRemaining is negative and represents the + system uptime when signalled */ +@@ -108,7 +112,11 @@ cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) + timeout->QuadPart = tbi.SignalState || tbi.TimeRemaining.QuadPart < 0LL + ? 0LL : tbi.TimeRemaining.QuadPart; + } +- NtCancelTimer (_my_tls.locals.cw_timer, NULL); ++ NtCancelTimer (wait_timer, NULL); ++ if (local_timer) ++ NtClose(local_timer); ++ else ++ _my_tls.locals.cw_timer_inuse = false; + } + + if (res == WAIT_CANCELED && is_cw_cancel_self) +diff --git a/winsup/cygwin/local_includes/cygtls.h b/winsup/cygwin/local_includes/cygtls.h +index e4e3889..4bd79c3 100644 +--- a/winsup/cygwin/local_includes/cygtls.h ++++ b/winsup/cygwin/local_includes/cygtls.h +@@ -135,6 +135,7 @@ struct _local_storage + + /* thread.cc */ + HANDLE cw_timer; ++ bool cw_timer_inuse; + + tls_pathbuf pathbufs; + char ttybuf[32]; +@@ -180,7 +181,7 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */ + siginfo_t *sigwait_info; + HANDLE signal_arrived; + bool will_wait_for_signal; +-#if 0 ++#if 1 + long __align; /* Needed to align context to 16 byte. */ + #endif + /* context MUST be aligned to 16 byte, otherwise RtlCaptureContext fails. +diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc +index 2c09b14..95c12ef 100644 +--- a/winsup/cygwin/select.cc ++++ b/winsup/cygwin/select.cc +@@ -385,10 +385,14 @@ next_while:; + to create the timer once per thread. Since WFMO checks the handles + in order, we append the timer as last object, otherwise it's preferred + over actual events on the descriptors. */ +- HANDLE &wait_timer = _my_tls.locals.cw_timer; ++ HANDLE local_timer = NULL; ++ HANDLE &wait_timer = ++ _my_tls.locals.cw_timer_inuse ? local_timer : _my_tls.locals.cw_timer; + if (us > 0LL) + { + NTSTATUS status; ++ if (!_my_tls.locals.cw_timer_inuse) ++ _my_tls.locals.cw_timer_inuse = true; + if (!wait_timer) + { + status = NtCreateTimer (&wait_timer, TIMER_ALL_ACCESS, NULL, +@@ -431,6 +435,10 @@ next_while:; + { + BOOLEAN current_state; + NtCancelTimer (wait_timer, ¤t_state); ++ if (local_timer) ++ NtClose (local_timer); ++ else ++ _my_tls.locals.cw_timer_inuse = false; + } + + wait_states res; diff --git a/msys2-runtime/0058-Cygwin-signal-Do-not-handle-signal-when-__SIGFLUSHFA.patch b/msys2-runtime/0058-Cygwin-signal-Do-not-handle-signal-when-__SIGFLUSHFA.patch new file mode 100644 index 00000000000..4c8293e85cb --- /dev/null +++ b/msys2-runtime/0058-Cygwin-signal-Do-not-handle-signal-when-__SIGFLUSHFA.patch @@ -0,0 +1,63 @@ +From 36734c9f0cf9b0230091db8523dc637ef6dfa82f Mon Sep 17 00:00:00 2001 +From: Takashi Yano +Date: Tue, 21 Jan 2025 00:13:04 +0900 +Subject: [PATCH 58/N] Cygwin: signal: Do not handle signal when + __SIGFLUSHFAST is sent + +The commit a22a0ad7c4f0 was not entirely correct. Even with the patch, +some hangs still occur. This patch overrides the previous commit along +with the patch that makes cygwait() reentrant, to fix these hangs. + +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 +Reviewed-by: Corinna Vinschen +Signed-off-by: Takashi Yano +(cherry picked from commit 83afe3e238cd12fb7d4799ba6b3c77e9e3618d91) +--- + winsup/cygwin/sigproc.cc | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc +index cf43aa9..858a7fd 100644 +--- a/winsup/cygwin/sigproc.cc ++++ b/winsup/cygwin/sigproc.cc +@@ -742,6 +742,9 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) + memcpy (p, si._si_commune._si_str, n); p += n; + } + ++ unsigned cw_mask; ++ cw_mask = pack.si.si_signo == __SIGFLUSHFAST ? 0 : cw_sig_restart; ++ + DWORD nb; + BOOL res; + /* Try multiple times to send if packsize != nb since that probably +@@ -751,8 +754,7 @@ 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) +- _my_tls.call_signal_handler (); ++ cygwait (NULL, 10, cw_mask); + res = 0; + } + +@@ -785,7 +787,7 @@ 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); ++ rc = cygwait (pack.wakeup, WSSC, cw_mask); + ForceCloseHandle (pack.wakeup); + } + else +@@ -806,9 +808,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) + { diff --git a/msys2-runtime/0059-Cygwin-signal-Avoid-frequent-TLS-lock-unlock-for-SIG.patch b/msys2-runtime/0059-Cygwin-signal-Avoid-frequent-TLS-lock-unlock-for-SIG.patch new file mode 100644 index 00000000000..f7eceaffdb4 --- /dev/null +++ b/msys2-runtime/0059-Cygwin-signal-Avoid-frequent-TLS-lock-unlock-for-SIG.patch @@ -0,0 +1,102 @@ +From 1da3384967da7dd6daa127cafdc853efc6680727 Mon Sep 17 00:00:00 2001 +From: Takashi Yano +Date: Sat, 18 Jan 2025 19:03:23 +0900 +Subject: [PATCH 59/N] Cygwin: signal: Avoid frequent TLS lock/unlock for + SIGCONT processing + +It seems that current _cygtls::handle_SIGCONT() code sometimes falls +into a deadlock due to frequent TLS lock/unlock operation in the +yield() loop. With this patch, the yield() in the wait loop is placed +outside the TLS lock to avoid frequent TLS lock/unlock. + +Fixes: 9ae51bcc51a7 ("Cygwin: signal: Fix another deadlock between main and sig thread") +Reviewed-by: Corinna Vinschen +Signed-off-by: Takashi Yano +--- + winsup/cygwin/exceptions.cc | 36 ++++++++++----------------- + winsup/cygwin/local_includes/cygtls.h | 4 +-- + 2 files changed, 15 insertions(+), 25 deletions(-) + +diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc +index 469052a..1cce7c8 100644 +--- a/winsup/cygwin/exceptions.cc ++++ b/winsup/cygwin/exceptions.cc +@@ -1420,7 +1420,7 @@ api_fatal_debug () + + /* Attempt to carefully handle SIGCONT when we are stopped. */ + void +-_cygtls::handle_SIGCONT (threadlist_t * &tl_entry) ++_cygtls::handle_SIGCONT () + { + if (NOTSTATE (myself, PID_STOPPED)) + return; +@@ -1431,23 +1431,17 @@ _cygtls::handle_SIGCONT (threadlist_t * &tl_entry) + Make sure that any pending signal is handled before trying to + send a new one. Then make sure that SIGCONT has been recognized + before exiting the loop. */ +- bool sigsent = false; +- while (1) +- if (sig) /* Assume that it's ok to just test sig outside of a +- lock since setup_handler does it this way. */ +- { +- cygheap->unlock_tls (tl_entry); +- yield (); /* Attempt to schedule another thread. */ +- tl_entry = cygheap->find_tls (_main_tls); +- } +- else if (sigsent) +- break; /* SIGCONT has been recognized by other thread */ +- else +- { +- sig = SIGCONT; +- set_signal_arrived (); /* alert sig_handle_tty_stop */ +- sigsent = true; +- } ++ while (sig) /* Assume that it's ok to just test sig outside of a */ ++ yield (); /* lock since setup_handler does it this way. */ ++ ++ lock (); ++ sig = SIGCONT; ++ set_signal_arrived (); /* alert sig_handle_tty_stop */ ++ unlock (); ++ ++ while (sig == SIGCONT) ++ yield (); ++ + /* Clear pending stop signals */ + sig_clear (SIGSTOP, false); + sig_clear (SIGTSTP, false); +@@ -1479,11 +1473,7 @@ sigpacket::process () + myself->rusage_self.ru_nsignals++; + + if (si.si_signo == SIGCONT) +- { +- tl_entry = cygheap->find_tls (_main_tls); +- _main_tls->handle_SIGCONT (tl_entry); +- cygheap->unlock_tls (tl_entry); +- } ++ _main_tls->handle_SIGCONT (); + + /* SIGKILL is special. It always goes through. */ + if (si.si_signo == SIGKILL) +diff --git a/winsup/cygwin/local_includes/cygtls.h b/winsup/cygwin/local_includes/cygtls.h +index 4bd79c3..328912f 100644 +--- a/winsup/cygwin/local_includes/cygtls.h ++++ b/winsup/cygwin/local_includes/cygtls.h +@@ -195,7 +195,7 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */ + class cygthread *_ctinfo; + class san *andreas; + waitq wq; +- int sig; ++ volatile int sig; + unsigned incyg; + volatile unsigned spinning; + volatile unsigned stacklock; +@@ -276,7 +276,7 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */ + { + will_wait_for_signal = false; + } +- void handle_SIGCONT (threadlist_t * &); ++ void handle_SIGCONT (); + static void cleanup_early(struct _reent *); + private: + void call2 (DWORD (*) (void *, void *), void *, void *); diff --git a/msys2-runtime/PKGBUILD b/msys2-runtime/PKGBUILD index aa87c6ff8ca..246a1a7ac89 100644 --- a/msys2-runtime/PKGBUILD +++ b/msys2-runtime/PKGBUILD @@ -4,7 +4,7 @@ pkgbase=msys2-runtime pkgname=('msys2-runtime' 'msys2-runtime-devel') pkgver=3.5.5 -pkgrel=2 +pkgrel=3 pkgdesc="Cygwin POSIX emulation engine" arch=('x86_64') url="https://www.cygwin.com/" @@ -81,9 +81,13 @@ source=('msys2-runtime'::git+https://github.com/cygwin/cygwin#tag=cygwin-${pkgve 0052-msys2-runtime-restore-fast-path-for-current-user-pri.patch 0053-Fix-SSH-hangs.patch 0054-Cygwin-signal-Do-not-handle-signal-when-__SIGFLUSHFA.patch - 0055-fixup-Avoid-sharing-cygheaps-across-Cygwin-versions.patch) + 0055-fixup-Avoid-sharing-cygheaps-across-Cygwin-versions.patch + 0056-fixup-Cygwin-signal-Do-not-handle-signal-when-__SIGF.patch + 0057-Cygwin-cygwait-Make-cygwait-reentrant.patch + 0058-Cygwin-signal-Do-not-handle-signal-when-__SIGFLUSHFA.patch + 0059-Cygwin-signal-Avoid-frequent-TLS-lock-unlock-for-SIG.patch) sha256sums=('b946762515173a45371a88060e9e672a4aaa290541fd6400660bf35a286a375f' - '1827504a147c8fb6f9a85a1051024018e3193d14c85c170a468409cf6365522b' + 'dba1028d2e161ce034b066acacade0280a4ddbded90636bd0cde8881cd78ede4' '76e37d572d2aba473aab8f5a1984af2084e6069f9195795c71bc45778edbd1eb' '5c79b09f9337cc8a5f993db6dd1f54df269f8390ab3348a94e5a139a5d060e39' 'ad84aab9a9f88b5f7510f04b33b77bbe380ce48e29a9a4feb54b485a3def3114' @@ -138,7 +142,11 @@ sha256sums=('b946762515173a45371a88060e9e672a4aaa290541fd6400660bf35a286a375f' '0bb8eda3871e4f639b933b5a5cdae089d70b55d9f52a9d5980d3c7ffec51dd17' '4e8127cea653273e44ef04a565d51a01c3d0e72307ccb6e374a6ff3c1dedd2a5' '20da59f62c2d4d051758e857eb78aa143821816f762bf1e84b5d1946d1ab1b03' - 'c3adb9d99255a025cd402c40b4a9923464818131fbe41c8df8d56747f6c4bf5e') + 'c3adb9d99255a025cd402c40b4a9923464818131fbe41c8df8d56747f6c4bf5e' + '97a7992a66b505eacf9203dc55d1746228089c96a2089801a623124a198fe238' + '7983913f1df1d744093c279d6f4e209dcb6ff97a56ecbfbcc39be961ef89546d' + '740740dbfcc73ae486c00f4de28fc94ef12149ca914f7777950936a482470969' + '7cecad758eae70038a4beaa611cbfcd403d3e2840dc2fb4a69de722f84df0cd7') # Helper macros to help make tasks easier # apply_patch_with_msg() { @@ -247,7 +255,11 @@ prepare() { 0052-msys2-runtime-restore-fast-path-for-current-user-pri.patch \ 0053-Fix-SSH-hangs.patch \ 0054-Cygwin-signal-Do-not-handle-signal-when-__SIGFLUSHFA.patch \ - 0055-fixup-Avoid-sharing-cygheaps-across-Cygwin-versions.patch + 0055-fixup-Avoid-sharing-cygheaps-across-Cygwin-versions.patch \ + 0056-fixup-Cygwin-signal-Do-not-handle-signal-when-__SIGF.patch \ + 0057-Cygwin-cygwait-Make-cygwait-reentrant.patch \ + 0058-Cygwin-signal-Do-not-handle-signal-when-__SIGFLUSHFA.patch \ + 0059-Cygwin-signal-Avoid-frequent-TLS-lock-unlock-for-SIG.patch } build() { diff --git a/msys2-runtime/msys2-runtime.commit b/msys2-runtime/msys2-runtime.commit index aa9175825a7..b1986fe40c1 100644 --- a/msys2-runtime/msys2-runtime.commit +++ b/msys2-runtime/msys2-runtime.commit @@ -1 +1 @@ -0202cf91276afa70860bdf948553cc03a1179b55 +1da3384967da7dd6daa127cafdc853efc6680727