From b680b9a26cffe3d8071ce0a19a3827d06b24bb2c Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye Date: Fri, 27 Sep 2019 21:03:13 +0000 Subject: [PATCH 1/6] Revert bpo-37878: Make PyThreadState_DeleteCurrent() Internal --- Doc/c-api/init.rst | 8 ++++++++ Include/cpython/pystate.h | 1 + Include/internal/pycore_pylifecycle.h | 2 -- Modules/_threadmodule.c | 2 +- Modules/_tracemalloc.c | 4 ++-- Python/pystate.c | 12 +++++++++--- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 0b7a84d031532e..5456ad446cf23f 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -1035,6 +1035,14 @@ All of the following functions must be called after :c:func:`Py_Initialize`. :c:func:`PyThreadState_Clear`. + .. c:function:: void PyThreadState_DeleteCurrent() + + Destroy the current thread state and release the global interpreter lock. + Like :c:func:`PyThreadState_Delete`, the global interpreter lock need not + be held. The thread state must have been reset with a previous call + to :c:func:`PyThreadState_Clear`. + + .. c:function:: PY_INT64_T PyInterpreterState_GetID(PyInterpreterState *interp) Return the interpreter's unique ID. If there was any error in doing diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index f8723517803673..e877d5c1a7e6d3 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -183,6 +183,7 @@ PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); +PyAPI_FUNC(void) PyThreadState_DeleteCurrent(); typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index cdf5c09a4262ba..29aff8b2561c12 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -110,8 +110,6 @@ PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb); -PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime); - #ifdef __cplusplus } #endif diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 1c7df3f8741474..2711a20586f075 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1028,7 +1028,7 @@ t_bootstrap(void *boot_raw) PyMem_DEL(boot_raw); tstate->interp->num_threads--; PyThreadState_Clear(tstate); - _PyThreadState_DeleteCurrent(runtime); + PyThreadState_DeleteCurrent(runtime); PyThread_exit_thread(); } diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 26d76004aaa52c..ee32ac29b7eea2 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -34,7 +34,7 @@ static struct { #if defined(TRACE_RAW_MALLOC) /* This lock is needed because tracemalloc_free() is called without the GIL held from PyMem_RawFree(). It cannot acquire the lock because it - would introduce a deadlock in _PyThreadState_DeleteCurrent(). */ + would introduce a deadlock in PyThreadState_DeleteCurrent(). */ static PyThread_type_lock tables_lock; # define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1) # define TABLES_UNLOCK() PyThread_release_lock(tables_lock) @@ -728,7 +728,7 @@ tracemalloc_free(void *ctx, void *ptr) return; /* GIL cannot be locked in PyMem_RawFree() because it would introduce - a deadlock in _PyThreadState_DeleteCurrent(). */ + a deadlock in PyThreadState_DeleteCurrent(). */ alloc->free(alloc->ctx, ptr); diff --git a/Python/pystate.c b/Python/pystate.c index 7dd8b7f866b5ea..27a04e3245c8ce 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -807,7 +807,7 @@ PyThreadState_Clear(PyThreadState *tstate) } -/* Common code for PyThreadState_Delete() and _PyThreadState_DeleteCurrent() */ +/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ static void tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) { @@ -856,14 +856,14 @@ PyThreadState_Delete(PyThreadState *tstate) } -void +static void _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) { struct _gilstate_runtime_state *gilstate = &runtime->gilstate; PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); if (tstate == NULL) Py_FatalError( - "_PyThreadState_DeleteCurrent: no current tstate"); + "PyThreadState_DeleteCurrent: no current tstate"); tstate_delete_common(runtime, tstate); if (gilstate->autoInterpreterState && PyThread_tss_get(&gilstate->autoTSSkey) == tstate) @@ -874,6 +874,12 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) PyEval_ReleaseLock(); } +void +PyThreadState_DeleteCurrent() +{ + _PyThreadState_DeleteCurrent(&_PyRuntime); +} + /* * Delete all thread states except the one passed as argument. From 7649d8dc93b405a3b2d80ea994bc9ca09b5c5907 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2019 12:53:56 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Misc/NEWS.d/next/C API/2019-10-03-12-53-53.bpo-38266.0FIC1q.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/C API/2019-10-03-12-53-53.bpo-38266.0FIC1q.rst diff --git a/Misc/NEWS.d/next/C API/2019-10-03-12-53-53.bpo-38266.0FIC1q.rst b/Misc/NEWS.d/next/C API/2019-10-03-12-53-53.bpo-38266.0FIC1q.rst new file mode 100644 index 00000000000000..3b4c4232eb897c --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-10-03-12-53-53.bpo-38266.0FIC1q.rst @@ -0,0 +1 @@ +Revert the removal of PyThreadState_DeleteCurrent() with documentation. \ No newline at end of file From 7acac6faec4f0a1bc36fcdd542f59d0c6f0b6eb9 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 3 Oct 2019 20:02:00 -0300 Subject: [PATCH 3/6] Revert bpo-37878: Make PyThreadState_DeleteCurrent() Internal --- Include/cpython/pystate.h | 2 +- Include/internal/pycore_pylifecycle.h | 3 ++- Modules/_threadmodule.c | 2 +- Modules/_tracemalloc.c | 4 ++-- Python/pystate.c | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index e877d5c1a7e6d3..6c8d2ae041ea54 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -183,7 +183,7 @@ PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); -PyAPI_FUNC(void) PyThreadState_DeleteCurrent(); +PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 29aff8b2561c12..9107e94d015e68 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -108,7 +108,8 @@ PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, - PyObject *value, PyObject *tb); + PyObject *value, PyObject *tb); +PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime); #ifdef __cplusplus } diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 2711a20586f075..1c7df3f8741474 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1028,7 +1028,7 @@ t_bootstrap(void *boot_raw) PyMem_DEL(boot_raw); tstate->interp->num_threads--; PyThreadState_Clear(tstate); - PyThreadState_DeleteCurrent(runtime); + _PyThreadState_DeleteCurrent(runtime); PyThread_exit_thread(); } diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index ee32ac29b7eea2..26d76004aaa52c 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -34,7 +34,7 @@ static struct { #if defined(TRACE_RAW_MALLOC) /* This lock is needed because tracemalloc_free() is called without the GIL held from PyMem_RawFree(). It cannot acquire the lock because it - would introduce a deadlock in PyThreadState_DeleteCurrent(). */ + would introduce a deadlock in _PyThreadState_DeleteCurrent(). */ static PyThread_type_lock tables_lock; # define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1) # define TABLES_UNLOCK() PyThread_release_lock(tables_lock) @@ -728,7 +728,7 @@ tracemalloc_free(void *ctx, void *ptr) return; /* GIL cannot be locked in PyMem_RawFree() because it would introduce - a deadlock in PyThreadState_DeleteCurrent(). */ + a deadlock in _PyThreadState_DeleteCurrent(). */ alloc->free(alloc->ctx, ptr); diff --git a/Python/pystate.c b/Python/pystate.c index 27a04e3245c8ce..9c4e0797cbec51 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -856,7 +856,7 @@ PyThreadState_Delete(PyThreadState *tstate) } -static void +void _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) { struct _gilstate_runtime_state *gilstate = &runtime->gilstate; @@ -875,7 +875,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) } void -PyThreadState_DeleteCurrent() +PyThreadState_DeleteCurrent(void) { _PyThreadState_DeleteCurrent(&_PyRuntime); } From 0c1a14d6836b50a30bbe77f8bb72de44d3a2add9 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 3 Oct 2019 21:19:14 -0300 Subject: [PATCH 4/6] remove unneccessary space diff --- Include/internal/pycore_pylifecycle.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 9107e94d015e68..4d73c11e5803cf 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -109,6 +109,7 @@ PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb); + PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime); #ifdef __cplusplus From c54ccac7a25b801da8c36ce45ddc89804ac81ce3 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 3 Oct 2019 21:30:47 -0300 Subject: [PATCH 5/6] Remove space --- Include/internal/pycore_pylifecycle.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 4d73c11e5803cf..fc0174a79ddd3d 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -111,7 +111,6 @@ PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb); PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime); - #ifdef __cplusplus } #endif From 331040923a8256cfa8d7a8fc04372a44fa740d2e Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 3 Oct 2019 21:49:17 -0300 Subject: [PATCH 6/6] Remove space --- Include/internal/pycore_pylifecycle.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index fc0174a79ddd3d..cdf5c09a4262ba 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -108,9 +108,10 @@ PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, - PyObject *value, PyObject *tb); + PyObject *value, PyObject *tb); PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime); + #ifdef __cplusplus } #endif