@@ -23,7 +23,7 @@ become problematic:
2323- They aren't safe for finalization, either causing the calling thread to hang or
2424 crashing it with a segmentation fault, preventing further execution.
2525- When they're called before finalization, they force the thread to be
26- "daemon", meaning that the interpreter won't wait for it to reach any point
26+ "daemon", meaning that an interpreter won't wait for it to reach any point
2727 of execution. This is mostly frustrating for developers, but can lead to
2828 deadlocks!
2929- Subinterpreters don't play nicely with them, because they all assume that
@@ -54,12 +54,12 @@ This is achieved by introducing two concepts into the C API:
5454
5555- "Daemon" and "non-daemon" threads, similar to how it works in the
5656 :mod: `threading ` module.
57- - Interpreter reference counts which prevent the interpreter from finalizing.
57+ - Interpreter reference counts which prevent an interpreter from finalizing.
5858
5959In :c:func: `PyThreadState_Ensure `, both of these ideas are applied. The
60- calling thread is to store a reference to the interpreter via
60+ calling thread is to store a reference to an interpreter via
6161:c:func: `PyInterpreterState_Hold `. :c:func: `PyInterpreterState_Hold `
62- increases the reference count of the interpreter, requiring the thread
62+ increases the reference count of an interpreter, requiring the thread
6363to finish (by eventually calling :c:func: `PyThreadState_Release `) before
6464beginning finalization.
6565
@@ -168,6 +168,8 @@ finalization, because a daemon thread got hung while holding the lock. There
168168are workarounds for this for pure-Python code, but native threads don't have
169169such an option.
170170
171+ .. _pep-788-hanging-compat :
172+
171173We can't change finalization behavior for ``PyGILState_Ensure ``
172174***************************************************************
173175
@@ -186,6 +188,11 @@ error, as noted in `python/cpython#124622 <https://github.com/python/cpython/iss
186188 proceed. The API was designed as "it'll block and only return once it has
187189 the GIL" without any other option.
188190
191+ For this reason, we can't make any real changes to how :c:func: `PyGILState_Ensure `
192+ works for finalization, because it would break existing code. Similarly, threads
193+ created with the existing C API will have to remain daemon, because extensions
194+ that implement native threads aren't guaranteed to work during finalization.
195+
189196The existing APIs are broken and misleading
190197-------------------------------------------
191198
@@ -330,7 +337,7 @@ that it always works. An approach that were to return a failure based on
330337the start-time of the thread could cause spurious issues.
331338
332339In the case where it is useful to let the interpreter finalize, such as in
333- a signal handler where there's no guarantee that the thread will start,
340+ an asynchronous callback where there's no guarantee that the thread will start,
334341strong references to an interpreter can be acquired through
335342:c:func: `PyInterpreterState_Lookup `.
336343
@@ -348,14 +355,12 @@ way). This generally happens when a thread calls :c:func:`PyEval_RestoreThread`
348355or in between bytecode instructions, based on :func: `sys.setswitchinterval `.
349356
350357A new, internal field will be added to the ``PyThreadState `` structure that
351- determines if the thread is daemon. If the thread is daemon, then it will
352- hang during attachment as usual, but if it's not, then the interpreter will
353- let the thread attach and continue execution. On with-GIL builds, this again
354- means handing off the GIL to the thread. During finalization, the interpreter
358+ determines if the thread is daemon. Before finalization, an interpreter
355359will wait until all non-daemon threads call :c:func: `PyThreadState_Delete `.
356360
357- For backwards compatibility, all thread states created by existing APIs will
358- remain daemon by default.
361+ For backwards compatibility, all thread states created by existing APIs,
362+ including :c:func: `PyGILState_Ensure `, will remain daemon by default.
363+ See :ref: `pep-788-hanging-compat `.
359364
360365.. c :function :: int PyThreadState_SetDaemon (int is_daemon)
361366
@@ -374,8 +379,8 @@ remain daemon by default.
374379Interpreter reference counting
375380------------------------------
376381
377- Internally, the interpreter will have to keep track of the number of
378- non-daemon native threads, which will determine when the interpreter can
382+ Internally, an interpreter will have to keep track of the number of
383+ non-daemon native threads, which will determine when an interpreter can
379384finalize. This is done to prevent use-after-free crashes in
380385:c:func:`PyThreadState_Ensure` for interpreters with short lifetimes, and
381386to remove needless layers of synchronization between the calling thread and
@@ -396,15 +401,15 @@ A non-zero reference count prevents the interpreter from finalizing.
396401 This function is generally meant to be used in tandem with
397402 :c:func:`PyThreadState_Ensure`.
398403
399- The caller must have an :term:`attached thread state`, and cannot return
400- ``NULL``. Failures are always a fatal error.
404+ The caller must have an :term:`attached thread state`. This function
405+ cannot return ``NULL``. Failures are always a fatal error.
401406
402407.. c:function:: PyInterpreterState *PyInterpreterState_Lookup(int64_t interp_id)
403408
404409 Similar to :c:func:`PyInterpreterState_Hold`, but looks up an interpreter
405410 based on an ID (see :c:func: `PyInterpreterState_GetID `). This has the
406411 benefit of allowing the interpreter to finalize in cases where the thread
407- might not start, such as inside of a signal handler .
412+ might not start, such as inside of an asynchronous callback .
408413
409414 This function will return ``NULL`` without an exception set on failure.
410415 If the return value is non-``NULL``, then the returned interpreter will be
@@ -438,7 +443,7 @@ replace :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`.
438443 there is a subsequent call to :c:func: `PyThreadState_Release ` that matches
439444 this one.
440445
441- The interpreter's *interp * reference count is decremented by one .
446+ The reference to the interpreter *interp * is stolen by this function .
442447 As such, *interp * should have been acquired by
443448 :c:func: `PyInterpreterState_Hold `.
444449
@@ -454,8 +459,9 @@ replace :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`.
454459
455460.. c:function:: void PyThreadState_Release()
456461
457- Detach and destroy the :term:`attached thread state` set by
458- :c:func:`PyThreadState_Ensure`.
462+ Release the :term:`attached thread state` set by
463+ :c:func:`PyThreadState_Ensure`. Any thread state that was set prior
464+ to the original call to :c:func:`PyThreadState_Ensure` will be restored.
459465
460466 This function cannot fail, but may hang the thread if the
461467 attached thread state prior to the original :c:func:`!PyThreadState_Ensure`
@@ -655,13 +661,13 @@ Asynchronous callback example
655661*****************************
656662
657663As stated in the Motivation _, there are many cases where it's desirable
658- to call Python in an asynchronous callback, such as a signal handler. In that
659- case, it's not safe to call :c:func: `PyInterpreterState_Hold `, because it's
660- not guaranteed that :c:func: `PyThreadState_Ensure ` will ever be called, which
661- would deadlock finalization.
664+ to call Python in an asynchronous callback. In such cases, it's not safe to
665+ call :c:func: `PyInterpreterState_Hold `, because it's not guaranteed that
666+ :c:func: `PyThreadState_Ensure ` will ever be called.
667+ If not, finalization becomes deadlocked .
662668
663- This scenario requires :c:func: `PyInterpreterState_Lookup `, which only prevents
664- finalization when the lookup has been made.
669+ This scenario requires using :c:func: `PyInterpreterState_Lookup ` instead,
670+ which only prevents finalization once the lookup has been made.
665671
666672For example:
667673
@@ -728,7 +734,7 @@ deleted and cause use-after-free violations. :c:func:`PyInterpreterState_Hold`
728734fixes this issue anyway, but an interpreter ID does have the benefit of
729735requiring less magic in the implementation, but has several downsides:
730736
731- - Nearly all existing APIs already return a :c:type: `PyInterpreterState `
737+ - Nearly all existing interpreter APIs already return a :c:type: `PyInterpreterState `
732738 pointer, not an interpreter ID. Functions like
733739 :c:func: `PyThreadState_GetInterpreter ` would have to be accompanied by
734740 frustrating calls to :c:func: `PyInterpreterState_GetID `. There's also
0 commit comments