Skip to content

bpo-37878: Make PyThreadState_DeleteCurrent() Internal #15315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Sep 5, 2019
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ Removed
standard :class:`bytes` objects are always used.
(Contributed by Jon Janzen in :issue:`36409`.)

* ``PyThreadState_DeleteCurrent()`` has been removed. It was not documented.
(Contributed by Joannah Nanjekye in :issue:`37878`.)


Porting to Python 3.9
=====================
Expand Down
2 changes: 2 additions & 0 deletions Include/internal/pycore_pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ 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
Expand Down
1 change: 0 additions & 1 deletion Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*);
PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *);
PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *);
PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *);
PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);

/* Get the current thread state.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make :c:func:`PyThreadState_DeleteCurrent` Internal.
9 changes: 7 additions & 2 deletions Modules/_threadmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -993,18 +993,21 @@ struct bootstate {
PyObject *args;
PyObject *keyw;
PyThreadState *tstate;
_PyRuntimeState *runtime;
};

static void
t_bootstrap(void *boot_raw)
{
struct bootstate *boot = (struct bootstate *) boot_raw;
PyThreadState *tstate;
_PyRuntimeState *runtime;
PyObject *res;

runtime = boot->runtime;
tstate = boot->tstate;
tstate->thread_id = PyThread_get_thread_ident();
_PyThreadState_Init(&_PyRuntime, tstate);
_PyThreadState_Init(runtime, tstate);
PyEval_AcquireThread(tstate);
tstate->interp->num_threads++;
res = PyObject_Call(boot->func, boot->args, boot->keyw);
Expand All @@ -1025,13 +1028,14 @@ t_bootstrap(void *boot_raw)
PyMem_DEL(boot_raw);
tstate->interp->num_threads--;
PyThreadState_Clear(tstate);
PyThreadState_DeleteCurrent();
_PyThreadState_DeleteCurrent(runtime);
PyThread_exit_thread();
}

static PyObject *
thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
{
_PyRuntimeState *runtime = &_PyRuntime;
PyObject *func, *args, *keyw = NULL;
struct bootstate *boot;
unsigned long ident;
Expand Down Expand Up @@ -1062,6 +1066,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
boot->args = args;
boot->keyw = keyw;
boot->tstate = _PyThreadState_Prealloc(boot->interp);
boot->runtime = runtime;
if (boot->tstate == NULL) {
PyMem_DEL(boot);
return PyErr_NoMemory();
Expand Down
4 changes: 2 additions & 2 deletions Modules/_tracemalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand Down
12 changes: 3 additions & 9 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,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)
{
Expand Down Expand Up @@ -858,14 +858,14 @@ PyThreadState_Delete(PyThreadState *tstate)
}


static void
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)
Expand All @@ -876,12 +876,6 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime)
PyEval_ReleaseLock();
}

void
PyThreadState_DeleteCurrent()
{
_PyThreadState_DeleteCurrent(&_PyRuntime);
}


/*
* Delete all thread states except the one passed as argument.
Expand Down