summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-04-24 15:14:33 (GMT)
committerGitHub <noreply@github.com>2019-04-24 15:14:33 (GMT)
commitb930a2d2b1247bdba560db341ba90a9cbb538eb3 (patch)
treeed2cd1a40f8150e1c498eca98427c9af4f1c7ada
parent8bb3230149538c25c1bacced5e64a3c071475f73 (diff)
downloadcpython-b930a2d2b1247bdba560db341ba90a9cbb538eb3.zip
cpython-b930a2d2b1247bdba560db341ba90a9cbb538eb3.tar.gz
cpython-b930a2d2b1247bdba560db341ba90a9cbb538eb3.tar.bz2
bpo-36710: PyOS_AfterFork_Child() pass runtime parameter (GH-12936)
The PyOS_AfterFork_Child() function now pass a 'runtime' parameter to subfunctions. * Fix _PyRuntimeState_ReInitThreads(): use the correct memory allocator * Add runtime parameter to _PyRuntimeState_ReInitThreads(), _PyGILState_Reinit() and _PyInterpreterState_DeleteExceptMain() * Move _PyGILState_Reinit() to the internal C API.
-rw-r--r--Include/cpython/pystate.h1
-rw-r--r--Include/internal/pycore_pystate.h12
-rw-r--r--Modules/posixmodule.c7
-rw-r--r--Python/pystate.c65
4 files changed, 43 insertions, 42 deletions
diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h
index 2341dda..94331f3 100644
--- a/Include/cpython/pystate.h
+++ b/Include/cpython/pystate.h
@@ -155,7 +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) _PyGILState_Reinit(void);
/* Similar to PyThreadState_Get(), but don't issue a fatal error
* if it is NULL. */
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index 509ca36..2c24f67 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -185,9 +185,9 @@ typedef struct pyruntimestate {
/* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */
PyAPI_DATA(_PyRuntimeState) _PyRuntime;
-PyAPI_FUNC(_PyInitError) _PyRuntimeState_Init(_PyRuntimeState *);
-PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *);
-PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(void);
+PyAPI_FUNC(_PyInitError) _PyRuntimeState_Init(_PyRuntimeState *runtime);
+PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
+PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
/* Initialize _PyRuntimeState.
Return NULL on success, or return an error message on failure. */
@@ -236,8 +236,10 @@ PyAPI_FUNC(void) _PyThreadState_Init(
PyThreadState *tstate);
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
-PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *);
-PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(void);
+PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
+PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);
+
+PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime);
#ifdef __cplusplus
}
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index e8dbdcc..56ec3ee 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -421,12 +421,13 @@ PyOS_AfterFork_Parent(void)
void
PyOS_AfterFork_Child(void)
{
- _PyGILState_Reinit();
- _PyInterpreterState_DeleteExceptMain();
+ _PyRuntimeState *runtime = &_PyRuntime;
+ _PyGILState_Reinit(runtime);
+ _PyInterpreterState_DeleteExceptMain(runtime);
PyEval_ReInitThreads();
_PyImport_ReInitLock();
_PySignal_AfterFork();
- _PyRuntimeState_ReInitThreads();
+ _PyRuntimeState_ReInitThreads(runtime);
run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
}
diff --git a/Python/pystate.c b/Python/pystate.c
index ef9d792..6aaf993 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -108,23 +108,31 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime)
*/
void
-_PyRuntimeState_ReInitThreads(void)
+_PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
{
// This was initially set in _PyRuntimeState_Init().
- _PyRuntime.main_thread = PyThread_get_thread_ident();
+ runtime->main_thread = PyThread_get_thread_ident();
+
+ /* Force default allocator, since _PyRuntimeState_Fini() must
+ use the same allocator than this function. */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ runtime->interpreters.mutex = PyThread_allocate_lock();
+ runtime->interpreters.main->id_mutex = PyThread_allocate_lock();
+ runtime->xidregistry.mutex = PyThread_allocate_lock();
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
- _PyRuntime.interpreters.mutex = PyThread_allocate_lock();
- if (_PyRuntime.interpreters.mutex == NULL) {
+ if (runtime->interpreters.mutex == NULL) {
Py_FatalError("Can't initialize lock for runtime interpreters");
}
- _PyRuntime.interpreters.main->id_mutex = PyThread_allocate_lock();
- if (_PyRuntime.interpreters.main->id_mutex == NULL) {
+ if (runtime->interpreters.main->id_mutex == NULL) {
Py_FatalError("Can't initialize ID lock for main interpreter");
}
- _PyRuntime.xidregistry.mutex = PyThread_allocate_lock();
- if (_PyRuntime.xidregistry.mutex == NULL) {
+ if (runtime->xidregistry.mutex == NULL) {
Py_FatalError("Can't initialize lock for cross-interpreter data registry");
}
}
@@ -290,20 +298,22 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
* is a current interpreter state, it *must* be the main interpreter.
*/
void
-_PyInterpreterState_DeleteExceptMain()
+_PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime)
{
+ struct pyinterpreters *interpreters = &runtime->interpreters;
+
PyThreadState *tstate = PyThreadState_Swap(NULL);
- if (tstate != NULL && tstate->interp != _PyRuntime.interpreters.main) {
+ if (tstate != NULL && tstate->interp != interpreters->main) {
Py_FatalError("PyInterpreterState_DeleteExceptMain: not main interpreter");
}
HEAD_LOCK();
- PyInterpreterState *interp = _PyRuntime.interpreters.head;
- _PyRuntime.interpreters.head = NULL;
+ PyInterpreterState *interp = interpreters->head;
+ interpreters->head = NULL;
while (interp != NULL) {
- if (interp == _PyRuntime.interpreters.main) {
- _PyRuntime.interpreters.main->next = NULL;
- _PyRuntime.interpreters.head = interp;
+ if (interp == interpreters->main) {
+ interpreters->main->next = NULL;
+ interpreters->head = interp;
interp = interp->next;
continue;
}
@@ -319,7 +329,7 @@ _PyInterpreterState_DeleteExceptMain()
}
HEAD_UNLOCK();
- if (_PyRuntime.interpreters.head == NULL) {
+ if (interpreters->head == NULL) {
Py_FatalError("PyInterpreterState_DeleteExceptMain: missing main");
}
PyThreadState_Swap(tstate);
@@ -1079,31 +1089,20 @@ _PyGILState_Fini(void)
* don't reset TSS upon fork(), see issue #10517.
*/
void
-_PyGILState_Reinit(void)
+_PyGILState_Reinit(_PyRuntimeState *runtime)
{
- /* Force default allocator, since _PyRuntimeState_Fini() must
- use the same allocator than this function. */
- PyMemAllocatorEx old_alloc;
- _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-
- _PyRuntime.interpreters.mutex = PyThread_allocate_lock();
-
- PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-
- if (_PyRuntime.interpreters.mutex == NULL) {
- Py_FatalError("Can't initialize threads for interpreter");
- }
-
+ struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
PyThreadState *tstate = PyGILState_GetThisThreadState();
- PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey);
- if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) {
+
+ PyThread_tss_delete(&gilstate->autoTSSkey);
+ if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) {
Py_FatalError("Could not allocate TSS entry");
}
/* If the thread had an associated auto thread state, reassociate it with
* the new key. */
if (tstate &&
- PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, (void *)tstate) != 0)
+ PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate) != 0)
{
Py_FatalError("Couldn't create autoTSSkey mapping");
}