summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-03-09 22:10:53 (GMT)
committerGitHub <noreply@github.com>2020-03-09 22:10:53 (GMT)
commit9229eeee105f19705f72e553cf066751ac47c7b7 (patch)
tree6ac7f6021117f7dfd939188d0bc296097fe93c4c /Python
parentb7e9525f9c7ef02a1d2ad8253afdeb733b0951d4 (diff)
downloadcpython-9229eeee105f19705f72e553cf066751ac47c7b7.zip
cpython-9229eeee105f19705f72e553cf066751ac47c7b7.tar.gz
cpython-9229eeee105f19705f72e553cf066751ac47c7b7.tar.bz2
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.
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval_gil.h19
1 files changed, 18 insertions, 1 deletions
diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h
index 03f04b9..9c051ae 100644
--- a/Python/ceval_gil.h
+++ b/Python/ceval_gil.h
@@ -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;
}