bpo-39877: take_gil() checks tstate_must_exit() twice by vstinner · Pull Request #18890 · python/cpython
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(); }
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; }