8000 bpo-39877: take_gil() checks tstate_must_exit() twice (GH-18890) · python/cpython@9229eee · GitHub
[go: up one dir, main page]

Skip to content

Commit 9229eee

Browse files
authored
bpo-39877: take_gil() checks tstate_must_exit() twice (GH-18890)
take_gil() now also checks tstate_must_exit() after acquiring the GIL: exit the thread if Py_Finalize() has been called.
1 parent b7e9525 commit 9229eee

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

Python/ceval_gil.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,13 @@ take_gil(PyThreadState *tstate)
213213

214214
assert(tstate != NULL);
215215

216-
/* Check if we should make a quick exit. */
217216
if (tstate_must_exit(tstate)) {
217+
/* bpo-39877: If Py_Finalize() has been called and tstate is not the
218+
thread which called Py_Finalize(), exit immediately the thread.
219+
220+
This code path can be reached by a daemon thread after Py_Finalize()
221+
completes. In this case, tstate is a dangling pointer: points to
222+
PyThreadState freed memory. */
218223
PyThread_exit_thread();
219224
}
220225

@@ -282,6 +287,18 @@ take_gil(PyThreadState *tstate)
282287

283288
MUTEX_UNLOCK(gil->mutex);
284289

290+
if (tstate_must_exit(tstate)) {
291+
/* bpo-36475: If Py_Finalize() has been called and tstate is not
292+
the thread which called Py_Finalize(), exit immediately the
293+
thread.
294+
295+
This code path can be reached by a daemon thread which was waiting
296+
in take_gil() while the main thread called
297+
wait_for_thread_shutdown() from Py_Finalize(). */
298+
drop_gil(ceval, tstate);
299+
PyThread_exit_thread();
300+
}
301+
285302
errno = err;
286303
}
287304

0 commit comments

Comments
 (0)
0