@@ -981,11 +981,19 @@ If any thread, other than the finalization thread, attempts to acquire the GIL
981981during finalization, either explicitly via :c:func:`PyGILState_Ensure`,
982982:c:macro:`Py_END_ALLOW_THREADS`, :c:func:`PyEval_AcquireThread`, or
983983:c:func:`PyEval_AcquireLock`, or implicitly when the interpreter attempts to
984- reacquire it after having yielded it, the thread enters a permanently blocked
985- state where it remains until the program exits. In most cases this is harmless,
986- but this can result in deadlock if a later stage of finalization attempts to
987- acquire a lock owned by the blocked thread, or otherwise waits on the blocked
988- thread.
984+ reacquire it after having yielded it, the thread enters **a permanently blocked
985+ state** where it remains until the program exits. In most cases this is
986+ harmless, but this can result in deadlock if a later stage of finalization
987+ attempts to acquire a lock owned by the blocked thread, or otherwise waits on
988+ the blocked thread.
989+
990+ Gross? Yes. This prevents random crashes and/or unexpectedly skipped C++
991+ finalizations further up the call stack when such threads were forcably exited
992+ here in CPython 3.13 and earlier. The CPython runtime GIL acquiring C APIs
993+ have never had any error reporting or handling expectations at GIL acquisition
994+ time that would've allowed for graceful exit from this situation. Changing that
995+ would require new stable C APIs and rewriting the majority of C code in the
996+ CPython ecosystem to use those with error handling.
989997
990998
991999High-level API
0 commit comments