Unverified Kaydet (Commit) 8bb32301 authored tarafından Victor Stinner's avatar Victor Stinner Kaydeden (comit) GitHub

bpo-36710: Add runtime parameter to _PyThreadState_Init() (GH-12935)

* Add 'runtime' parameter to _PyThreadState_Init()
* Add 'gilstate' parameter to _PyGILState_NoteThreadState()
* Move _PyThreadState_Init() and _PyThreadState_DeleteExcept()
   to the internal C API.
üst 6c44fde3
...@@ -155,8 +155,6 @@ PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void); ...@@ -155,8 +155,6 @@ PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void);
PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*);
PyAPI_FUNC(void) _PyState_ClearModules(void); PyAPI_FUNC(void) _PyState_ClearModules(void);
PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); 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); PyAPI_FUNC(void) _PyGILState_Reinit(void);
/* Similar to PyThreadState_Get(), but don't issue a fatal error /* Similar to PyThreadState_Get(), but don't issue a fatal error
......
...@@ -231,6 +231,11 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void); ...@@ -231,6 +231,11 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void);
/* Other */ /* 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(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *);
PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(void); PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(void);
......
...@@ -994,7 +994,7 @@ t_bootstrap(void *boot_raw) ...@@ -994,7 +994,7 @@ t_bootstrap(void *boot_raw)
tstate = boot->tstate; tstate = boot->tstate;
tstate->thread_id = PyThread_get_thread_ident(); tstate->thread_id = PyThread_get_thread_ident();
_PyThreadState_Init(tstate); _PyThreadState_Init(&_PyRuntime, tstate);
PyEval_AcquireThread(tstate); PyEval_AcquireThread(tstate);
tstate->interp->num_threads++; tstate->interp->num_threads++;
res = PyObject_Call(boot->func, boot->args, boot->keyw); res = PyObject_Call(boot->func, boot->args, boot->keyw);
......
...@@ -133,7 +133,9 @@ _PyRuntimeState_ReInitThreads(void) ...@@ -133,7 +133,9 @@ _PyRuntimeState_ReInitThreads(void)
WAIT_LOCK) WAIT_LOCK)
#define HEAD_UNLOCK() PyThread_release_lock(_PyRuntime.interpreters.mutex) #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 _PyInitError
_PyInterpreterState_Enable(_PyRuntimeState *runtime) _PyInterpreterState_Enable(_PyRuntimeState *runtime)
...@@ -487,71 +489,74 @@ static PyThreadState * ...@@ -487,71 +489,74 @@ static PyThreadState *
new_threadstate(PyInterpreterState *interp, int init) new_threadstate(PyInterpreterState *interp, int init)
{ {
PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState));
if (tstate == NULL) {
return NULL;
}
if (_PyThreadState_GetFrame == NULL) if (_PyThreadState_GetFrame == NULL) {
_PyThreadState_GetFrame = threadstate_getframe; _PyThreadState_GetFrame = threadstate_getframe;
}
if (tstate != NULL) { tstate->interp = interp;
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->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->dict = NULL;
tstate->curexc_value = NULL;
tstate->curexc_traceback = NULL;
tstate->exc_state.exc_type = NULL; tstate->curexc_type = NULL;
tstate->exc_state.exc_value = NULL; tstate->curexc_value = NULL;
tstate->exc_state.exc_traceback = NULL; tstate->curexc_traceback = NULL;
tstate->exc_state.previous_item = NULL;
tstate->exc_info = &tstate->exc_state;
tstate->c_profilefunc = NULL; tstate->exc_state.exc_type = NULL;
tstate->c_tracefunc = NULL; tstate->exc_state.exc_value = NULL;
tstate->c_profileobj = NULL; tstate->exc_state.exc_traceback = NULL;
tstate->c_traceobj = NULL; tstate->exc_state.previous_item = NULL;
tstate->exc_info = &tstate->exc_state;
tstate->trash_delete_nesting = 0; tstate->c_profilefunc = NULL;
tstate->trash_delete_later = NULL; tstate->c_tracefunc = NULL;
tstate->on_delete = NULL; tstate->c_profileobj = NULL;
tstate->on_delete_data = 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->coroutine_origin_tracking_depth = 0;
tstate->in_coroutine_wrapper = 0;
tstate->async_gen_firstiter = NULL; tstate->coroutine_wrapper = NULL;
tstate->async_gen_finalizer = NULL; tstate->in_coroutine_wrapper = 0;
tstate->context = NULL; tstate->async_gen_firstiter = NULL;
tstate->context_ver = 1; tstate->async_gen_finalizer = NULL;
tstate->id = ++interp->tstate_next_unique_id; tstate->context = NULL;
tstate->context_ver = 1;
if (init) tstate->id = ++interp->tstate_next_unique_id;
_PyThreadState_Init(tstate);
HEAD_LOCK(); if (init) {
tstate->prev = NULL; _PyThreadState_Init(&_PyRuntime, tstate);
tstate->next = interp->tstate_head;
if (tstate->next)
tstate->next->prev = tstate;
interp->tstate_head = tstate;
HEAD_UNLOCK();
} }
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; return tstate;
} }
...@@ -568,9 +573,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp) ...@@ -568,9 +573,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp)
} }
void void
_PyThreadState_Init(PyThreadState *tstate) _PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate)
{ {
_PyGILState_NoteThreadState(tstate); _PyGILState_NoteThreadState(&runtime->gilstate, tstate);
} }
PyObject* PyObject*
...@@ -1037,17 +1042,23 @@ PyThreadState_IsCurrent(PyThreadState *tstate) ...@@ -1037,17 +1042,23 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
Py_Initialize/Py_FinalizeEx Py_Initialize/Py_FinalizeEx
*/ */
void void
_PyGILState_Init(PyInterpreterState *i, PyThreadState *t) _PyGILState_Init(PyInterpreterState *interp, PyThreadState *tstate)
{ {
assert(i && t); /* must init with valid states */ /* must init with valid states */
if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) { 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"); Py_FatalError("Could not allocate TSS entry");
} }
_PyRuntime.gilstate.autoInterpreterState = i; gilstate->autoInterpreterState = interp;
assert(PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL); assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL);
assert(t->gilstate_counter == 0); assert(tstate->gilstate_counter == 0);
_PyGILState_NoteThreadState(t); _PyGILState_NoteThreadState(gilstate, tstate);
} }
PyInterpreterState * PyInterpreterState *
...@@ -1104,13 +1115,14 @@ _PyGILState_Reinit(void) ...@@ -1104,13 +1115,14 @@ _PyGILState_Reinit(void)
a better fix for SF bug #1010677 than the first one attempted). a better fix for SF bug #1010677 than the first one attempted).
*/ */
static void 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 /* If autoTSSkey isn't initialized, this must be the very first
threadstate created in Py_Initialize(). Don't do anything for now threadstate created in Py_Initialize(). Don't do anything for now
(we'll be back here when _PyGILState_Init is called). */ (we'll be back here when _PyGILState_Init is called). */
if (!_PyRuntime.gilstate.autoInterpreterState) if (!gilstate->autoInterpreterState) {
return; return;
}
/* Stick the thread state for this thread in thread specific storage. /* Stick the thread state for this thread in thread specific storage.
...@@ -1124,10 +1136,8 @@ _PyGILState_NoteThreadState(PyThreadState* tstate) ...@@ -1124,10 +1136,8 @@ _PyGILState_NoteThreadState(PyThreadState* tstate)
The first thread state created for that given OS level thread will The first thread state created for that given OS level thread will
"win", which seems reasonable behaviour. "win", which seems reasonable behaviour.
*/ */
if (PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL) { if (PyThread_tss_get(&gilstate->autoTSSkey) == NULL) {
if ((PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, (void *)tstate) if ((PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate)) != 0) {
) != 0)
{
Py_FatalError("Couldn't create autoTSSkey mapping"); Py_FatalError("Couldn't create autoTSSkey mapping");
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment