@@ -23,7 +23,7 @@ become problematic:
23
23
- They aren't safe for finalization, either causing the calling thread to hang or
24
24
crashing it with a segmentation fault, preventing further execution.
25
25
- 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
27
27
of execution. This is mostly frustrating for developers, but can lead to
28
28
deadlocks!
29
29
- 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:
54
54
55
55
- "Daemon" and "non-daemon" threads, similar to how it works in the
56
56
:mod: `threading ` module.
57
- - Interpreter reference counts which prevent the interpreter from finalizing.
57
+ - Interpreter reference counts which prevent an interpreter from finalizing.
58
58
59
59
In :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
61
61
: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
63
63
to finish (by eventually calling :c:func: `PyThreadState_Release `) before
64
64
beginning finalization.
65
65
@@ -168,6 +168,8 @@ finalization, because a daemon thread got hung while holding the lock. There
168
168
are workarounds for this for pure-Python code, but native threads don't have
169
169
such an option.
170
170
171
+ .. _pep-788-hanging-compat :
172
+
171
173
We can't change finalization behavior for ``PyGILState_Ensure ``
172
174
***************************************************************
173
175
@@ -186,6 +188,11 @@ error, as noted in `python/cpython#124622 <https://github.com/python/cpython/iss
186
188
proceed. The API was designed as "it'll block and only return once it has
187
189
the GIL" without any other option.
188
190
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
+
189
196
The existing APIs are broken and misleading
190
197
-------------------------------------------
191
198
@@ -330,7 +337,7 @@ that it always works. An approach that were to return a failure based on
330
337
the start-time of the thread could cause spurious issues.
331
338
332
339
In 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,
334
341
strong references to an interpreter can be acquired through
335
342
:c:func: `PyInterpreterState_Lookup `.
336
343
@@ -348,14 +355,12 @@ way). This generally happens when a thread calls :c:func:`PyEval_RestoreThread`
348
355
or in between bytecode instructions, based on :func: `sys.setswitchinterval `.
349
356
350
357
A 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
355
359
will wait until all non-daemon threads call :c:func: `PyThreadState_Delete `.
356
360
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 `.
359
364
360
365
.. c :function :: int PyThreadState_SetDaemon (int is_daemon)
361
366
@@ -374,8 +379,8 @@ remain daemon by default.
374
379
Interpreter reference counting
375
380
------------------------------
376
381
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
379
384
finalize. This is done to prevent use-after-free crashes in
380
385
:c:func:`PyThreadState_Ensure` for interpreters with short lifetimes, and
381
386
to remove needless layers of synchronization between the calling thread and
@@ -396,15 +401,15 @@ A non-zero reference count prevents the interpreter from finalizing.
396
401
This function is generally meant to be used in tandem with
397
402
:c:func:`PyThreadState_Ensure`.
398
403
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.
401
406
402
407
.. c:function:: PyInterpreterState *PyInterpreterState_Lookup(int64_t interp_id)
403
408
404
409
Similar to :c:func:`PyInterpreterState_Hold`, but looks up an interpreter
405
410
based on an ID (see :c:func: `PyInterpreterState_GetID `). This has the
406
411
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 .
408
413
409
414
This function will return ``NULL`` without an exception set on failure.
410
415
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`.
438
443
there is a subsequent call to :c:func: `PyThreadState_Release ` that matches
439
444
this one.
440
445
441
- The interpreter's *interp * reference count is decremented by one .
446
+ The reference to the interpreter *interp * is stolen by this function .
442
447
As such, *interp * should have been acquired by
443
448
:c:func: `PyInterpreterState_Hold `.
444
449
@@ -454,8 +459,9 @@ replace :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`.
454
459
455
460
.. c:function:: void PyThreadState_Release()
456
461
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.
459
465
460
466
This function cannot fail, but may hang the thread if the
461
467
attached thread state prior to the original :c:func:`!PyThreadState_Ensure`
@@ -655,13 +661,13 @@ Asynchronous callback example
655
661
*****************************
656
662
657
663
As 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 .
662
668
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.
665
671
666
672
For example:
667
673
@@ -728,7 +734,7 @@ deleted and cause use-after-free violations. :c:func:`PyInterpreterState_Hold`
728
734
fixes this issue anyway, but an interpreter ID does have the benefit of
729
735
requiring less magic in the implementation, but has several downsides:
730
736
731
- - Nearly all existing APIs already return a :c:type: `PyInterpreterState `
737
+ - Nearly all existing interpreter APIs already return a :c:type: `PyInterpreterState `
732
738
pointer, not an interpreter ID. Functions like
733
739
:c:func: `PyThreadState_GetInterpreter ` would have to be accompanied by
734
740
frustrating calls to :c:func: `PyInterpreterState_GetID `. There's also
0 commit comments