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.
This commit is contained in:
parent
b7e9525f9c
commit
9229eeee10
|
@ -213,8 +213,13 @@ take_gil(PyThreadState *tstate)
|
|||
|
||||
assert(tstate != NULL);
|
||||
|
||||
/* Check if we should make a quick exit. */
|
||||
if (tstate_must_exit(tstate)) {
|
||||
/* bpo-39877: If Py_Finalize() has been called and tstate is not the
|
||||
thread which called Py_Finalize(), exit immediately the thread.
|
||||
|
||||
This code path can be reached by a daemon thread after Py_Finalize()
|
||||
completes. In this case, tstate is a dangling pointer: points to
|
||||
PyThreadState freed memory. */
|
||||
PyThread_exit_thread();
|
||||
}
|
||||
|
||||
|
@ -282,6 +287,18 @@ _ready:
|
|||
|
||||
MUTEX_UNLOCK(gil->mutex);
|
||||
|
||||
if (tstate_must_exit(tstate)) {
|
||||
/* bpo-36475: If Py_Finalize() has been called and tstate is not
|
||||
the thread which called Py_Finalize(), exit immediately the
|
||||
thread.
|
||||
|
||||
This code path can be reached by a daemon thread which was waiting
|
||||
in take_gil() while the main thread called
|
||||
wait_for_thread_shutdown() from Py_Finalize(). */
|
||||
drop_gil(ceval, tstate);
|
||||
PyThread_exit_thread();
|
||||
}
|
||||
|
||||
errno = err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue