STINNER Victor <[email protected]> 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 <[email protected]>
<https://bugs.python.org/issue36479>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com