Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4ae0149

Browse files
njsmithvstinner
authored andcommitted
bpo-30038: fix race condition in signal delivery + wakeup fd (#1082)
Before, it was possible to get the following sequence ofevents (especially on Windows, where the C-level signal handler forSIGINT is run in a separate thread):- SIGINT arrives- trip_signal is called- trip_signal writes to the wakeup fd- the main thread wakes up from select()-or-equivalent- the main thread checks for pending signals, but doesn't see any- the main thread drains the wakeup fd- the main thread goes back to sleep- trip_signal sets is_tripped=1 and calls Py_AddPendingCall to notify the main thread the it should run the Python-level signal handler- the main thread doesn't notice because it's asleepThis has been causing repeated failures in the Trio test suite:python-trio/trio#119
1 parentfca224f commit4ae0149

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

‎Modules/signalmodule.c‎

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,32 @@ trip_signal(int sig_num)
244244

245245
Handlers[sig_num].tripped=1;
246246

247+
if (!is_tripped) {
248+
/* Set is_tripped after setting .tripped, as it gets
249+
cleared in PyErr_CheckSignals() before .tripped. */
250+
is_tripped=1;
251+
Py_AddPendingCall(checksignals_witharg,NULL);
252+
}
253+
254+
/* And then write to the wakeup fd *after* setting all the globals and
255+
doing the Py_AddPendingCall. We used to write to the wakeup fd and then
256+
set the flag, but this allowed the following sequence of events
257+
(especially on windows, where trip_signal runs in a new thread):
258+
259+
- main thread blocks on select([wakeup_fd], ...)
260+
- signal arrives
261+
- trip_signal writes to the wakeup fd
262+
- the main thread wakes up
263+
- the main thread checks the signal flags, sees that they're unset
264+
- the main thread empties the wakeup fd
265+
- the main thread goes back to sleep
266+
- trip_signal sets the flags to request the Python-level signal handler
267+
be run
268+
- the main thread doesn't notice, because it's asleep
269+
270+
See bpo-30038 for more details.
271+
*/
272+
247273
#ifdefMS_WINDOWS
248274
fd=Py_SAFE_DOWNCAST(wakeup.fd,SOCKET_T,int);
249275
#else
@@ -281,13 +307,6 @@ trip_signal(int sig_num)
281307
}
282308
}
283309
}
284-
285-
if (!is_tripped) {
286-
/* Set is_tripped after setting .tripped, as it gets
287-
cleared in PyErr_CheckSignals() before .tripped. */
288-
is_tripped=1;
289-
Py_AddPendingCall(checksignals_witharg,NULL);
290-
}
291310
}
292311

293312
staticvoid

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp