diff options
author | Victor Stinner <vstinner@python.org> | 2020-03-09 22:10:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-09 22:10:53 (GMT) |
commit | 9229eeee105f19705f72e553cf066751ac47c7b7 (patch) | |
tree | 6ac7f6021117f7dfd939188d0bc296097fe93c4c /Python | |
parent | b7e9525f9c7ef02a1d2ad8253afdeb733b0951d4 (diff) | |
download | cpython-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.h | 19 |
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; } |