Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Include/cpython/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,6 @@ PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void);
PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*);
PyAPI_FUNC(void) _PyState_ClearModules(void);
PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *);
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
PyAPI_FUNC(void) _PyGILState_Reinit(void);

/* Similar to PyThreadState_Get(), but don't issue a fatal error
Expand Down
5 changes: 5 additions & 0 deletions Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void);

/* Other */

PyAPI_FUNC(void) _PyThreadState_Init(
_PyRuntimeState *runtime,
PyThreadState *tstate);
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);

PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *);
PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(void);

Expand Down
2 changes: 1 addition & 1 deletion Modules/_threadmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ t_bootstrap(void *boot_raw)

tstate = boot->tstate;
tstate->thread_id = PyThread_get_thread_ident();
_PyThreadState_Init(tstate);
_PyThreadState_Init(&_PyRuntime, tstate);
PyEval_AcquireThread(tstate);
tstate->interp->num_threads++;
res = PyObject_Call(boot->func, boot->args, boot->keyw);
Expand Down
138 changes: 74 additions & 64 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ _PyRuntimeState_ReInitThreads(void)
WAIT_LOCK)
#define HEAD_UNLOCK() PyThread_release_lock(_PyRuntime.interpreters.mutex)

static void _PyGILState_NoteThreadState(PyThreadState* tstate);
/* Forward declaration */
static void _PyGILState_NoteThreadState(
struct _gilstate_runtime_state *gilstate, PyThreadState* tstate);

_PyInitError
_PyInterpreterState_Enable(_PyRuntimeState *runtime)
Expand Down Expand Up @@ -487,71 +489,74 @@ static PyThreadState *
new_threadstate(PyInterpreterState *interp, int init)
{
PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState));
if (tstate == NULL) {
return NULL;
}

if (_PyThreadState_GetFrame == NULL)
if (_PyThreadState_GetFrame == NULL) {
_PyThreadState_GetFrame = threadstate_getframe;
}

if (tstate != NULL) {
tstate->interp = interp;

tstate->frame = NULL;
tstate->recursion_depth = 0;
tstate->overflowed = 0;
tstate->recursion_critical = 0;
tstate->stackcheck_counter = 0;
tstate->tracing = 0;
tstate->use_tracing = 0;
tstate->gilstate_counter = 0;
tstate->async_exc = NULL;
tstate->thread_id = PyThread_get_thread_ident();
tstate->interp = interp;

tstate->dict = NULL;
tstate->frame = NULL;
tstate->recursion_depth = 0;
tstate->overflowed = 0;
tstate->recursion_critical = 0;
tstate->stackcheck_counter = 0;
tstate->tracing = 0;
tstate->use_tracing = 0;
tstate->gilstate_counter = 0;
tstate->async_exc = NULL;
tstate->thread_id = PyThread_get_thread_ident();

tstate->curexc_type = NULL;
tstate->curexc_value = NULL;
tstate->curexc_traceback = NULL;
tstate->dict = NULL;

tstate->exc_state.exc_type = NULL;
tstate->exc_state.exc_value = NULL;
tstate->exc_state.exc_traceback = NULL;
tstate->exc_state.previous_item = NULL;
tstate->exc_info = &tstate->exc_state;
tstate->curexc_type = NULL;
tstate->curexc_value = NULL;
tstate->curexc_traceback = NULL;

tstate->c_profilefunc = NULL;
tstate->c_tracefunc = NULL;
tstate->c_profileobj = NULL;
tstate->c_traceobj = NULL;
tstate->exc_state.exc_type = NULL;
tstate->exc_state.exc_value = NULL;
tstate->exc_state.exc_traceback = NULL;
tstate->exc_state.previous_item = NULL;
tstate->exc_info = &tstate->exc_state;

tstate->trash_delete_nesting = 0;
tstate->trash_delete_later = NULL;
tstate->on_delete = NULL;
tstate->on_delete_data = NULL;
tstate->c_profilefunc = NULL;
tstate->c_tracefunc = NULL;
tstate->c_profileobj = NULL;
tstate->c_traceobj = NULL;

tstate->coroutine_origin_tracking_depth = 0;
tstate->trash_delete_nesting = 0;
tstate->trash_delete_later = NULL;
tstate->on_delete = NULL;
tstate->on_delete_data = NULL;

tstate->coroutine_wrapper = NULL;
tstate->in_coroutine_wrapper = 0;
tstate->coroutine_origin_tracking_depth = 0;

tstate->async_gen_firstiter = NULL;
tstate->async_gen_finalizer = NULL;
tstate->coroutine_wrapper = NULL;
tstate->in_coroutine_wrapper = 0;

tstate->context = NULL;
tstate->context_ver = 1;
tstate->async_gen_firstiter = NULL;
tstate->async_gen_finalizer = NULL;

tstate->id = ++interp->tstate_next_unique_id;
tstate->context = NULL;
tstate->context_ver = 1;

if (init)
_PyThreadState_Init(tstate);
tstate->id = ++interp->tstate_next_unique_id;

HEAD_LOCK();
tstate->prev = NULL;
tstate->next = interp->tstate_head;
if (tstate->next)
tstate->next->prev = tstate;
interp->tstate_head = tstate;
HEAD_UNLOCK();
if (init) {
_PyThreadState_Init(&_PyRuntime, tstate);
}

HEAD_LOCK();
tstate->prev = NULL;
tstate->next = interp->tstate_head;
if (tstate->next)
tstate->next->prev = tstate;
interp->tstate_head = tstate;
HEAD_UNLOCK();

return tstate;
}

Expand All @@ -568,9 +573,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp)
}

void
_PyThreadState_Init(PyThreadState *tstate)
_PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate)
{
_PyGILState_NoteThreadState(tstate);
_PyGILState_NoteThreadState(&runtime->gilstate, tstate);
}

PyObject*
Expand Down Expand Up @@ -1037,17 +1042,23 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
Py_Initialize/Py_FinalizeEx
*/
void
_PyGILState_Init(PyInterpreterState *i, PyThreadState *t)
_PyGILState_Init(PyInterpreterState *interp, PyThreadState *tstate)
{
assert(i && t); /* must init with valid states */
if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) {
/* must init with valid states */
assert(interp != NULL);
assert(tstate != NULL);

_PyRuntimeState *runtime = &_PyRuntime;
struct _gilstate_runtime_state *gilstate = &runtime->gilstate;

if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) {
Py_FatalError("Could not allocate TSS entry");
}
_PyRuntime.gilstate.autoInterpreterState = i;
assert(PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL);
assert(t->gilstate_counter == 0);
gilstate->autoInterpreterState = interp;
assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL);
assert(tstate->gilstate_counter == 0);

_PyGILState_NoteThreadState(t);
_PyGILState_NoteThreadState(gilstate, tstate);
}

PyInterpreterState *
Expand Down Expand Up @@ -1104,13 +1115,14 @@ _PyGILState_Reinit(void)
a better fix for SF bug #1010677 than the first one attempted).
*/
static void
_PyGILState_NoteThreadState(PyThreadState* tstate)
_PyGILState_NoteThreadState(struct _gilstate_runtime_state *gilstate, PyThreadState* tstate)
{
/* If autoTSSkey isn't initialized, this must be the very first
threadstate created in Py_Initialize(). Don't do anything for now
(we'll be back here when _PyGILState_Init is called). */
if (!_PyRuntime.gilstate.autoInterpreterState)
if (!gilstate->autoInterpreterState) {
return;
}

/* Stick the thread state for this thread in thread specific storage.

Expand All @@ -1124,10 +1136,8 @@ _PyGILState_NoteThreadState(PyThreadState* tstate)
The first thread state created for that given OS level thread will
"win", which seems reasonable behaviour.
*/
if (PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL) {
if ((PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, (void *)tstate)
) != 0)
{
if (PyThread_tss_get(&gilstate->autoTSSkey) == NULL) {
if ((PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate)) != 0) {
Py_FatalError("Couldn't create autoTSSkey mapping");
}
}
Expand Down