@@ -270,46 +270,23 @@ updated to switch over to terms like
270270:term: `"global interpreter lock" <global interpreter lock> `, so this namespace
271271seems to fit well for this PEP.
272272
273- Specification
274- =============
275-
276- Interpreter reference counting
277- ------------------------------
278-
279- Internally, the interpreter will have to keep track of a reference count
280- field, which will determine when the interpreter state is actually
281- deallocated. This is done to prevent use-after-free crashes in
282- :c:func: `PyThreadState_Ensure ` for interpreters with short lifetimes.
283-
284- An interpreter state returned by :c:func: `Py_NewInterpreter ` (or really,
285- :c:func: `PyInterpreterState_New `) will start with a reference count of 1, and
286- :c:func: `PyInterpreterState_Delete ` will decrement the reference count. If the
287- new reference count is zero, :c:func: `PyInterpreterState_Delete ` will
288- deallocate the interpreter state. However, the reference count will *not *
289- prevent the interpreter from finalizing.
290-
291- .. c :function :: PyInterpreterState *PyInterpreterState_Hold (void)
292-
293- Similar to :c:func:`PyInterpreterState_Get`, but returns a strong
294- reference to the interpreter (meaning, it has its reference count
295- incremented by one, allowing the returned interpreter state to be safely
296- accessed by another thread).
297-
298- This function is generally meant to be used in tandem with
299- :c:func:`PyThreadState_Ensure`.
300-
301- The caller must have an :term:`attached thread state`, and cannot return
302- ``NULL``. Failures are always a fatal error.
303-
304-
305- .. c:function:: void PyInterpreterState_Release(PyInterpreterState *interp)
273+ Preventing interpreter finalization with references
274+ ---------------------------------------------------
306275
307- Decrement the reference count of the interpreter, as was incremented by
308- :c:func: `PyInterpreterState_Hold `.
276+ Several iterations of this API have taken an approach where
277+ :c:func: `PyThreadState_Ensure ` can return a failure based on the state of
278+ the interpreter. Instead, this PEP takes an approach where an interpreter
279+ keeps track of the number of non-daemon threads, which inherently prevents
280+ it from beginning finalization.
309281
310- This function cannot fail, other than with a fatal error. The caller must
311- have an :term: `attached thread state ` for *interp *.
282+ The main upside with this approach is that there's more consistency with
283+ attaching threads. Using an interpreter reference from the calling thread
284+ keeps the interpreter from finalizing before the thread starts, ensuring
285+ that it always works. An approach that were to return a failure based on
286+ the start-time of the thread could cause spurious issues.
312287
288+ Specification
289+ =============
313290
314291Daemon and non-daemon threads
315292-----------------------------
@@ -344,8 +321,43 @@ remain daemon by default.
344321 :attr:`threading.Thread.daemon`.
345322
346323 Return zero on success, non-zero *without* an exception set on failure.
347- Failure generally means that threads have already finalized for the
348- current interpreter.
324+
325+ Interpreter reference counting
326+ ------------------------------
327+
328+ Internally, the interpreter will have to keep track of the number of
329+ non-daemon native threads, which will determine when the interpreter can
330+ finalize. This is done to prevent use-after-free crashes in
331+ :c:func:`PyThreadState_Ensure` for interpreters with short lifetimes, and
332+ to remove needless layers of synchronization between the calling thread and
333+ the started thread.
334+
335+ An interpreter state returned by :c:func:`Py_NewInterpreter` (or really,
336+ :c:func: `PyInterpreterState_New `) will start with a native thread countdown.
337+ For simplicity's sake, this will be referred to as a reference count.
338+ A non-zero reference count prevents the interpreter from finalizing.
339+
340+ .. c:function:: PyInterpreterState *PyInterpreterState_Hold(void)
341+
342+ Similar to :c:func:`PyInterpreterState_Get`, but returns a strong
343+ reference to the interpreter (meaning, it has its reference count
344+ incremented by one, allowing the returned interpreter state to be safely
345+ accessed by another thread, because it will be prevented from finalizing).
346+
347+ This function is generally meant to be used in tandem with
348+ :c:func:`PyThreadState_Ensure`.
349+
350+ The caller must have an :term:`attached thread state`, and cannot return
351+ ``NULL``. Failures are always a fatal error.
352+
353+
354+ .. c:function:: void PyInterpreterState_Release(PyInterpreterState *interp)
355+
356+ Decrement the reference count of the interpreter, as was incremented by
357+ :c:func: `PyInterpreterState_Hold `.
358+
359+ This function cannot fail, other than with a fatal error. The caller must
360+ have an :term: `attached thread state ` for *interp *.
349361
350362Ensuring and releasing thread states
351363------------------------------------
0 commit comments