STINNER Victor <vstin...@python.org> added the comment:
I suggest to close this issue, I don't think that it can be implemented because of daemon threads. -- > This behavior should instead be triggered by the thread's interpreter > finalizing rather than the runtime. What is the motivation for that? -- take_gil() cannot access interp->finalizing since interp memory is freed during Python finalization. take_gil() can only rely on a global variable like _PyRuntime to check if a daemon thread must exit during the Python finalization. I modified take_gil() recently to fix 2 or 3 different crashes caused by daemon threads during Python finalization. Extract of ceval.c: /* Check if a Python thread must exit immediately, rather than taking the GIL if Py_Finalize() has been called. When this function is called by a daemon thread after Py_Finalize() has been called, the GIL does no longer exist. tstate must be non-NULL. */ static inline int tstate_must_exit(PyThreadState *tstate) { /* bpo-39877: Access _PyRuntime directly rather than using tstate->interp->runtime to support calls from Python daemon threads. After Py_Finalize() has been called, tstate can be a dangling pointer: point to PyThreadState freed memory. */ _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime); return (finalizing != NULL && finalizing != tstate); } And simplified take_gil(): static void take_gil(PyThreadState *tstate) { 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(); } (... logic to acquire the GIL ...) if (must_exit) { /* 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, ceval2, tstate); PyThread_exit_thread(); } } ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue36479> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com