Skip to content

Commit 9832c04

Browse files
authored
Merge pull request #208 from git-for-windows/msys2-runtime-1da3384967da7dd6daa127cafdc853efc6680727
msys2-runtime: update to 1da3384967da7dd6daa127cafdc853efc6680727
2 parents 84c6716 + 6aaf44d commit 9832c04

6 files changed

+401
-6
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
From 7ad033fa4834dae3c44a6baeaa6a697c080bc5d2 Mon Sep 17 00:00:00 2001
2+
From: Takashi Yano <[email protected]>
3+
Date: Tue, 21 Jan 2025 12:15:33 +0900
4+
Subject: [PATCH 56/N] fixup! Cygwin: signal: Do not handle signal when
5+
__SIGFLUSHFAST is sent
6+
7+
This reverts commit a22a0ad7c4f0 to apply a new patch for the same
8+
purpose.
9+
10+
Signed-off-by: Takashi Yano <[email protected]>
11+
---
12+
winsup/cygwin/release/3.5.6 | 5 -----
13+
winsup/cygwin/sigproc.cc | 20 +++++---------------
14+
2 files changed, 5 insertions(+), 20 deletions(-)
15+
delete mode 100644 winsup/cygwin/release/3.5.6
16+
17+
diff --git a/winsup/cygwin/release/3.5.6 b/winsup/cygwin/release/3.5.6
18+
deleted file mode 100644
19+
index 643d58e..0000000
20+
--- a/winsup/cygwin/release/3.5.6
21+
+++ /dev/null
22+
@@ -1,5 +0,0 @@
23+
-Fixes:
24+
-------
25+
-
26+
-- Fix zsh hang at startup.
27+
- Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256954.html
28+
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
29+
index c298527..cf43aa9 100644
30+
--- a/winsup/cygwin/sigproc.cc
31+
+++ b/winsup/cygwin/sigproc.cc
32+
@@ -751,14 +751,10 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
33+
res = WriteFile (sendsig, leader, packsize, &nb, NULL);
34+
if (!res || packsize == nb)
35+
break;
36+
- if (cygwait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED
37+
- && pack.si.si_signo != __SIGFLUSHFAST)
38+
+ if (cygwait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED)
39+
_my_tls.call_signal_handler ();
40+
res = 0;
41+
}
42+
- /* Re-assert signal_arrived which has been cleared in cygwait(). */
43+
- if (_my_tls.sig)
44+
- _my_tls.set_signal_arrived ();
45+
46+
if (!res)
47+
{
48+
@@ -789,16 +785,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
49+
if (wait_for_completion)
50+
{
51+
sigproc_printf ("Waiting for pack.wakeup %p", pack.wakeup);
52+
- do
53+
- {
54+
- rc = cygwait (pack.wakeup, WSSC, cw_sig_eintr);
55+
- if (rc == WAIT_SIGNALED && pack.si.si_signo != __SIGFLUSHFAST)
56+
- _my_tls.call_signal_handler ();
57+
- }
58+
- while (rc != WAIT_OBJECT_0 && rc != WAIT_TIMEOUT);
59+
- /* Re-assert signal_arrived which has been cleared in cygwait(). */
60+
- if (_my_tls.sig)
61+
- _my_tls.set_signal_arrived ();
62+
+ rc = cygwait (pack.wakeup, WSSC);
63+
ForceCloseHandle (pack.wakeup);
64+
}
65+
else
66+
@@ -819,6 +806,9 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
67+
rc = -1;
68+
}
69+
70+
+ if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
71+
+ _my_tls.call_signal_handler ();
72+
+
73+
out:
74+
if (communing && rc)
75+
{
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
From 28e4e5594d8f838c39dd307b08e5e7d2d577bc97 Mon Sep 17 00:00:00 2001
2+
From: Takashi Yano <[email protected]>
3+
Date: Mon, 20 Jan 2025 23:54:56 +0900
4+
Subject: [PATCH 57/N] Cygwin: cygwait: Make cygwait() reentrant
5+
6+
To allow cygwait() to be called in the signal handler, a locally
7+
created timer is used instead of _cygtls::locals.cw_timer if it is
8+
in use.
9+
10+
Co-Authored-By: Corinna Vinschen <[email protected]>
11+
Signed-off-by: Takashi Yano <[email protected]>
12+
(cherry picked from commit ea1914000adcbed5c16fc0ba2676173b2f6016c4)
13+
---
14+
winsup/cygwin/cygtls.cc | 2 ++
15+
winsup/cygwin/cygwait.cc | 22 +++++++++++++++-------
16+
winsup/cygwin/local_includes/cygtls.h | 3 ++-
17+
winsup/cygwin/select.cc | 10 +++++++++-
18+
4 files changed, 28 insertions(+), 9 deletions(-)
19+
20+
diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc
21+
index afaee8e..b8b5a01 100644
22+
--- a/winsup/cygwin/cygtls.cc
23+
+++ b/winsup/cygwin/cygtls.cc
24+
@@ -64,6 +64,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
25+
initialized = CYGTLS_INITIALIZED;
26+
errno_addr = &(local_clib._errno);
27+
locals.cw_timer = NULL;
28+
+ locals.cw_timer_inuse = false;
29+
locals.pathbufs.clear ();
30+
31+
if ((void *) func == (void *) cygthread::stub
32+
@@ -85,6 +86,7 @@ _cygtls::fixup_after_fork ()
33+
signal_arrived = NULL;
34+
locals.select.sockevt = NULL;
35+
locals.cw_timer = NULL;
36+
+ locals.cw_timer_inuse = false;
37+
locals.pathbufs.clear ();
38+
wq.thread_ev = NULL;
39+
}
40+
diff --git a/winsup/cygwin/cygwait.cc b/winsup/cygwin/cygwait.cc
41+
index dbbe1db..bb653f6 100644
42+
--- a/winsup/cygwin/cygwait.cc
43+
+++ b/winsup/cygwin/cygwait.cc
44+
@@ -58,16 +58,20 @@ cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
45+
}
46+
47+
DWORD timeout_n;
48+
+ HANDLE local_timer = NULL;
49+
+ HANDLE &wait_timer =
50+
+ _my_tls.locals.cw_timer_inuse ? local_timer : _my_tls.locals.cw_timer;
51+
if (!timeout)
52+
timeout_n = WAIT_TIMEOUT + 1;
53+
else
54+
{
55+
+ if (!_my_tls.locals.cw_timer_inuse)
56+
+ _my_tls.locals.cw_timer_inuse = true;
57+
timeout_n = WAIT_OBJECT_0 + num++;
58+
- if (!_my_tls.locals.cw_timer)
59+
- NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
60+
- NotificationTimer);
61+
- NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
62+
- wait_objects[timeout_n] = _my_tls.locals.cw_timer;
63+
+ if (!wait_timer)
64+
+ NtCreateTimer (&wait_timer, TIMER_ALL_ACCESS, NULL, NotificationTimer);
65+
+ NtSetTimer (wait_timer, timeout, NULL, NULL, FALSE, 0, NULL);
66+
+ wait_objects[timeout_n] = wait_timer;
67+
}
68+
69+
while (1)
70+
@@ -100,7 +104,7 @@ cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
71+
{
72+
TIMER_BASIC_INFORMATION tbi;
73+
74+
- NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
75+
+ NtQueryTimer (wait_timer, TimerBasicInformation, &tbi,
76+
sizeof tbi, NULL);
77+
/* if timer expired, TimeRemaining is negative and represents the
78+
system uptime when signalled */
79+
@@ -108,7 +112,11 @@ cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
80+
timeout->QuadPart = tbi.SignalState || tbi.TimeRemaining.QuadPart < 0LL
81+
? 0LL : tbi.TimeRemaining.QuadPart;
82+
}
83+
- NtCancelTimer (_my_tls.locals.cw_timer, NULL);
84+
+ NtCancelTimer (wait_timer, NULL);
85+
+ if (local_timer)
86+
+ NtClose(local_timer);
87+
+ else
88+
+ _my_tls.locals.cw_timer_inuse = false;
89+
}
90+
91+
if (res == WAIT_CANCELED && is_cw_cancel_self)
92+
diff --git a/winsup/cygwin/local_includes/cygtls.h b/winsup/cygwin/local_includes/cygtls.h
93+
index e4e3889..4bd79c3 100644
94+
--- a/winsup/cygwin/local_includes/cygtls.h
95+
+++ b/winsup/cygwin/local_includes/cygtls.h
96+
@@ -135,6 +135,7 @@ struct _local_storage
97+
98+
/* thread.cc */
99+
HANDLE cw_timer;
100+
+ bool cw_timer_inuse;
101+
102+
tls_pathbuf pathbufs;
103+
char ttybuf[32];
104+
@@ -180,7 +181,7 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
105+
siginfo_t *sigwait_info;
106+
HANDLE signal_arrived;
107+
bool will_wait_for_signal;
108+
-#if 0
109+
+#if 1
110+
long __align; /* Needed to align context to 16 byte. */
111+
#endif
112+
/* context MUST be aligned to 16 byte, otherwise RtlCaptureContext fails.
113+
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
114+
index 2c09b14..95c12ef 100644
115+
--- a/winsup/cygwin/select.cc
116+
+++ b/winsup/cygwin/select.cc
117+
@@ -385,10 +385,14 @@ next_while:;
118+
to create the timer once per thread. Since WFMO checks the handles
119+
in order, we append the timer as last object, otherwise it's preferred
120+
over actual events on the descriptors. */
121+
- HANDLE &wait_timer = _my_tls.locals.cw_timer;
122+
+ HANDLE local_timer = NULL;
123+
+ HANDLE &wait_timer =
124+
+ _my_tls.locals.cw_timer_inuse ? local_timer : _my_tls.locals.cw_timer;
125+
if (us > 0LL)
126+
{
127+
NTSTATUS status;
128+
+ if (!_my_tls.locals.cw_timer_inuse)
129+
+ _my_tls.locals.cw_timer_inuse = true;
130+
if (!wait_timer)
131+
{
132+
status = NtCreateTimer (&wait_timer, TIMER_ALL_ACCESS, NULL,
133+
@@ -431,6 +435,10 @@ next_while:;
134+
{
135+
BOOLEAN current_state;
136+
NtCancelTimer (wait_timer, &current_state);
137+
+ if (local_timer)
138+
+ NtClose (local_timer);
139+
+ else
140+
+ _my_tls.locals.cw_timer_inuse = false;
141+
}
142+
143+
wait_states res;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
From 36734c9f0cf9b0230091db8523dc637ef6dfa82f Mon Sep 17 00:00:00 2001
2+
From: Takashi Yano <[email protected]>
3+
Date: Tue, 21 Jan 2025 00:13:04 +0900
4+
Subject: [PATCH 58/N] Cygwin: signal: Do not handle signal when
5+
__SIGFLUSHFAST is sent
6+
7+
The commit a22a0ad7c4f0 was not entirely correct. Even with the patch,
8+
some hangs still occur. This patch overrides the previous commit along
9+
with the patch that makes cygwait() reentrant, to fix these hangs.
10+
11+
Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256954.html
12+
Fixes: d243e51ef1d3 ("Cygwin: signal: Fix deadlock between main thread and sig thread")
13+
Reported-by: Daisuke Fujimura <[email protected]>
14+
Reviewed-by: Corinna Vinschen <[email protected]>
15+
Signed-off-by: Takashi Yano <[email protected]>
16+
(cherry picked from commit 83afe3e238cd12fb7d4799ba6b3c77e9e3618d91)
17+
---
18+
winsup/cygwin/sigproc.cc | 11 +++++------
19+
1 file changed, 5 insertions(+), 6 deletions(-)
20+
21+
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
22+
index cf43aa9..858a7fd 100644
23+
--- a/winsup/cygwin/sigproc.cc
24+
+++ b/winsup/cygwin/sigproc.cc
25+
@@ -742,6 +742,9 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
26+
memcpy (p, si._si_commune._si_str, n); p += n;
27+
}
28+
29+
+ unsigned cw_mask;
30+
+ cw_mask = pack.si.si_signo == __SIGFLUSHFAST ? 0 : cw_sig_restart;
31+
+
32+
DWORD nb;
33+
BOOL res;
34+
/* Try multiple times to send if packsize != nb since that probably
35+
@@ -751,8 +754,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
36+
res = WriteFile (sendsig, leader, packsize, &nb, NULL);
37+
if (!res || packsize == nb)
38+
break;
39+
- if (cygwait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED)
40+
- _my_tls.call_signal_handler ();
41+
+ cygwait (NULL, 10, cw_mask);
42+
res = 0;
43+
}
44+
45+
@@ -785,7 +787,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
46+
if (wait_for_completion)
47+
{
48+
sigproc_printf ("Waiting for pack.wakeup %p", pack.wakeup);
49+
- rc = cygwait (pack.wakeup, WSSC);
50+
+ rc = cygwait (pack.wakeup, WSSC, cw_mask);
51+
ForceCloseHandle (pack.wakeup);
52+
}
53+
else
54+
@@ -806,9 +808,6 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
55+
rc = -1;
56+
}
57+
58+
- if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
59+
- _my_tls.call_signal_handler ();
60+
-
61+
out:
62+
if (communing && rc)
63+
{
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
From 1da3384967da7dd6daa127cafdc853efc6680727 Mon Sep 17 00:00:00 2001
2+
From: Takashi Yano <[email protected]>
3+
Date: Sat, 18 Jan 2025 19:03:23 +0900
4+
Subject: [PATCH 59/N] Cygwin: signal: Avoid frequent TLS lock/unlock for
5+
SIGCONT processing
6+
7+
It seems that current _cygtls::handle_SIGCONT() code sometimes falls
8+
into a deadlock due to frequent TLS lock/unlock operation in the
9+
yield() loop. With this patch, the yield() in the wait loop is placed
10+
outside the TLS lock to avoid frequent TLS lock/unlock.
11+
12+
Fixes: 9ae51bcc51a7 ("Cygwin: signal: Fix another deadlock between main and sig thread")
13+
Reviewed-by: Corinna Vinschen <[email protected]>
14+
Signed-off-by: Takashi Yano <[email protected]>
15+
---
16+
winsup/cygwin/exceptions.cc | 36 ++++++++++-----------------
17+
winsup/cygwin/local_includes/cygtls.h | 4 +--
18+
2 files changed, 15 insertions(+), 25 deletions(-)
19+
20+
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
21+
index 469052a..1cce7c8 100644
22+
--- a/winsup/cygwin/exceptions.cc
23+
+++ b/winsup/cygwin/exceptions.cc
24+
@@ -1420,7 +1420,7 @@ api_fatal_debug ()
25+
26+
/* Attempt to carefully handle SIGCONT when we are stopped. */
27+
void
28+
-_cygtls::handle_SIGCONT (threadlist_t * &tl_entry)
29+
+_cygtls::handle_SIGCONT ()
30+
{
31+
if (NOTSTATE (myself, PID_STOPPED))
32+
return;
33+
@@ -1431,23 +1431,17 @@ _cygtls::handle_SIGCONT (threadlist_t * &tl_entry)
34+
Make sure that any pending signal is handled before trying to
35+
send a new one. Then make sure that SIGCONT has been recognized
36+
before exiting the loop. */
37+
- bool sigsent = false;
38+
- while (1)
39+
- if (sig) /* Assume that it's ok to just test sig outside of a
40+
- lock since setup_handler does it this way. */
41+
- {
42+
- cygheap->unlock_tls (tl_entry);
43+
- yield (); /* Attempt to schedule another thread. */
44+
- tl_entry = cygheap->find_tls (_main_tls);
45+
- }
46+
- else if (sigsent)
47+
- break; /* SIGCONT has been recognized by other thread */
48+
- else
49+
- {
50+
- sig = SIGCONT;
51+
- set_signal_arrived (); /* alert sig_handle_tty_stop */
52+
- sigsent = true;
53+
- }
54+
+ while (sig) /* Assume that it's ok to just test sig outside of a */
55+
+ yield (); /* lock since setup_handler does it this way. */
56+
+
57+
+ lock ();
58+
+ sig = SIGCONT;
59+
+ set_signal_arrived (); /* alert sig_handle_tty_stop */
60+
+ unlock ();
61+
+
62+
+ while (sig == SIGCONT)
63+
+ yield ();
64+
+
65+
/* Clear pending stop signals */
66+
sig_clear (SIGSTOP, false);
67+
sig_clear (SIGTSTP, false);
68+
@@ -1479,11 +1473,7 @@ sigpacket::process ()
69+
myself->rusage_self.ru_nsignals++;
70+
71+
if (si.si_signo == SIGCONT)
72+
- {
73+
- tl_entry = cygheap->find_tls (_main_tls);
74+
- _main_tls->handle_SIGCONT (tl_entry);
75+
- cygheap->unlock_tls (tl_entry);
76+
- }
77+
+ _main_tls->handle_SIGCONT ();
78+
79+
/* SIGKILL is special. It always goes through. */
80+
if (si.si_signo == SIGKILL)
81+
diff --git a/winsup/cygwin/local_includes/cygtls.h b/winsup/cygwin/local_includes/cygtls.h
82+
index 4bd79c3..328912f 100644
83+
--- a/winsup/cygwin/local_includes/cygtls.h
84+
+++ b/winsup/cygwin/local_includes/cygtls.h
85+
@@ -195,7 +195,7 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
86+
class cygthread *_ctinfo;
87+
class san *andreas;
88+
waitq wq;
89+
- int sig;
90+
+ volatile int sig;
91+
unsigned incyg;
92+
volatile unsigned spinning;
93+
volatile unsigned stacklock;
94+
@@ -276,7 +276,7 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
95+
{
96+
will_wait_for_signal = false;
97+
}
98+
- void handle_SIGCONT (threadlist_t * &);
99+
+ void handle_SIGCONT ();
100+
static void cleanup_early(struct _reent *);
101+
private:
102+
void call2 (DWORD (*) (void *, void *), void *, void *);

0 commit comments

Comments
 (0)