diff options
author | Victor Stinner <vstinner@python.org> | 2020-04-08 15:54:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-08 15:54:59 (GMT) |
commit | dda5d6e071c6a9d65993d45b90232565cfad2cde (patch) | |
tree | e5c629500c9557ecad3113054a019fc4af19f93a /Python/pylifecycle.c | |
parent | ac2cfe6631b77a2005d8f16f034dbb6154f04ab2 (diff) | |
download | cpython-dda5d6e071c6a9d65993d45b90232565cfad2cde.zip cpython-dda5d6e071c6a9d65993d45b90232565cfad2cde.tar.gz cpython-dda5d6e071c6a9d65993d45b90232565cfad2cde.tar.bz2 |
bpo-40226: PyInterpreterState_Delete() deletes pending calls (GH-19436)
PyInterpreterState_New() is now responsible to create pending calls,
PyInterpreterState_Delete() now deletes pending calls.
* Rename _PyEval_InitThreads() to _PyEval_InitGIL() and rename
_PyEval_InitGIL() to _PyEval_FiniGIL().
* _PyEval_InitState() and PyEval_FiniState() now create and delete
pending calls. _PyEval_InitState() now returns -1 on memory
allocation failure.
* Add init_interp_create_gil() helper function: code shared by
Py_NewInterpreter() and Py_InitializeFromConfig().
* init_interp_create_gil() now also calls _PyEval_FiniGIL(),
_PyEval_InitGIL() and _PyGILState_Init() in subinterpreters, but
these functions now do nothing when called from a subinterpreter.
Diffstat (limited to 'Python/pylifecycle.c')
-rw-r--r-- | Python/pylifecycle.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 2d5cb0f..9b413c6 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -524,6 +524,31 @@ pycore_init_runtime(_PyRuntimeState *runtime, static PyStatus +init_interp_create_gil(PyThreadState *tstate) +{ + PyStatus status; + + /* finalize_interp_delete() comment explains why _PyEval_FiniGIL() is + only called here. */ + _PyEval_FiniGIL(tstate); + + /* Auto-thread-state API */ + status = _PyGILState_Init(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* Create the GIL and take it */ + status = _PyEval_InitGIL(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + return _PyStatus_OK(); +} + + +static PyStatus pycore_create_interpreter(_PyRuntimeState *runtime, const PyConfig *config, PyThreadState **tstate_p) @@ -544,21 +569,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime, } (void) PyThreadState_Swap(tstate); - /* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because - destroying the GIL might fail when it is being referenced from - another running thread (see issue #9901). - Instead we destroy the previously created GIL here, which ensures - that we can call Py_Initialize / Py_FinalizeEx multiple times. */ - _PyEval_FiniThreads(tstate); - - /* Auto-thread-state API */ - status = _PyGILState_Init(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* Create the GIL and the pending calls lock */ - status = _PyEval_InitThreads(tstate); + status = init_interp_create_gil(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1323,6 +1334,12 @@ finalize_interp_delete(PyThreadState *tstate) _PyGILState_Fini(tstate); } + /* We can't call _PyEval_FiniGIL() here because destroying the GIL lock can + fail when it is being awaited by another running daemon thread (see + bpo-9901). Instead pycore_create_interpreter() destroys the previously + created GIL, which ensures that Py_Initialize / Py_FinalizeEx can be + called multiple times. */ + PyInterpreterState_Delete(tstate->interp); } @@ -1578,8 +1595,7 @@ new_interpreter(PyThreadState **tstate_p) goto error; } - /* Create the pending calls lock */ - status = _PyEval_InitThreads(tstate); + status = init_interp_create_gil(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } |