summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-04-24 15:24:01 (GMT)
committerGitHub <noreply@github.com>2019-04-24 15:24:01 (GMT)
commit8e91c246e468515b877690e090c73f496552541d (patch)
treed538530b4ac5ccf9aa6dc1e229410b8848eeb4f3
parent70bf713617e15fad390ed953e48b3c65d9bc90ec (diff)
downloadcpython-8e91c246e468515b877690e090c73f496552541d.zip
cpython-8e91c246e468515b877690e090c73f496552541d.tar.gz
cpython-8e91c246e468515b877690e090c73f496552541d.tar.bz2
bpo-36710: Add runtime variable to Py_FinalizeEx() (GH-12937)
* Add a 'runtime' variable to Py_FinalizeEx() rather than working directly on the global variable _PyRuntime * Add a 'runtime' parameter to _PyGC_Fini(), _PyGILState_Fini() and call_ll_exitfuncs()
-rw-r--r--Include/internal/pycore_pylifecycle.h6
-rw-r--r--Modules/gcmodule.c5
-rw-r--r--Python/pylifecycle.c35
-rw-r--r--Python/pystate.c7
4 files changed, 29 insertions, 24 deletions
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index bfff24b..f07bc42 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -8,6 +8,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_pystate.h" /* _PyRuntimeState */
+
/* True if the main interpreter thread exited due to an unhandled
* KeyboardInterrupt exception, suggesting the user pressed ^C. */
PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt;
@@ -63,7 +65,7 @@ extern void PyAsyncGen_Fini(void);
extern void _PyExc_Fini(void);
extern void _PyImport_Fini(void);
extern void _PyImport_Fini2(void);
-extern void _PyGC_Fini(void);
+extern void _PyGC_Fini(_PyRuntimeState *runtime);
extern void _PyType_Fini(void);
extern void _Py_HashRandomization_Fini(void);
extern void _PyUnicode_Fini(void);
@@ -73,7 +75,7 @@ extern void _PyHash_Fini(void);
extern int _PyTraceMalloc_Fini(void);
extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);
-extern void _PyGILState_Fini(void);
+extern void _PyGILState_Fini(_PyRuntimeState *runtime);
PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void);
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index a75d5fe..f36c7f5 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1865,9 +1865,10 @@ _PyGC_DumpShutdownStats(void)
}
void
-_PyGC_Fini(void)
+_PyGC_Fini(_PyRuntimeState *runtime)
{
- Py_CLEAR(_PyRuntime.gc.callbacks);
+ struct _gc_runtime_state *gc = &runtime->gc;
+ Py_CLEAR(gc->callbacks);
}
/* for debugging */
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index c7920ef..fe4cb97 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -65,7 +65,7 @@ static _PyInitError init_sys_streams(PyInterpreterState *interp);
static _PyInitError initsigs(void);
static void call_py_exitfuncs(PyInterpreterState *);
static void wait_for_thread_shutdown(void);
-static void call_ll_exitfuncs(void);
+static void call_ll_exitfuncs(_PyRuntimeState *runtime);
int _Py_UnhandledKeyboardInterrupt = 0;
_PyRuntimeState _PyRuntime = _PyRuntimeState_INIT;
@@ -1131,23 +1131,23 @@ flush_std_files(void)
int
Py_FinalizeEx(void)
{
- PyInterpreterState *interp;
- PyThreadState *tstate;
int status = 0;
- if (!_PyRuntime.initialized)
+ _PyRuntimeState *runtime = &_PyRuntime;
+ if (!runtime->initialized) {
return status;
+ }
// Wrap up existing "threading"-module-created, non-daemon threads.
wait_for_thread_shutdown();
- /* Get current thread state and interpreter pointer */
- tstate = _PyThreadState_GET();
- interp = tstate->interp;
-
// Make any remaining pending calls.
_Py_FinishPendingCalls();
+ /* Get current thread state and interpreter pointer */
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyInterpreterState *interp = tstate->interp;
+
/* The interpreter is still entirely intact at this point, and the
* exit funcs may be relying on that. In particular, if some thread
* or exit func is still waiting to do an import, the import machinery
@@ -1174,9 +1174,9 @@ Py_FinalizeEx(void)
/* Remaining threads (e.g. daemon threads) will automatically exit
after taking the GIL (in PyEval_RestoreThread()). */
- _PyRuntime.finalizing = tstate;
- _PyRuntime.initialized = 0;
- _PyRuntime.core_initialized = 0;
+ runtime->finalizing = tstate;
+ runtime->initialized = 0;
+ runtime->core_initialized = 0;
/* Flush sys.stdout and sys.stderr */
if (flush_std_files() < 0) {
@@ -1294,7 +1294,7 @@ Py_FinalizeEx(void)
PyFloat_Fini();
PyDict_Fini();
PySlice_Fini();
- _PyGC_Fini();
+ _PyGC_Fini(runtime);
_Py_HashRandomization_Fini();
_PyArg_Fini();
PyAsyncGen_Fini();
@@ -1314,7 +1314,7 @@ Py_FinalizeEx(void)
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
/* Cleanup auto-thread-state */
- _PyGILState_Fini();
+ _PyGILState_Fini(runtime);
/* Delete current thread. After this, many C API calls become crashy. */
PyThreadState_Swap(NULL);
@@ -1336,7 +1336,7 @@ Py_FinalizeEx(void)
}
#endif
- call_ll_exitfuncs();
+ call_ll_exitfuncs(runtime);
_PyRuntime_Finalize();
return status;
@@ -2223,10 +2223,11 @@ int Py_AtExit(void (*func)(void))
}
static void
-call_ll_exitfuncs(void)
+call_ll_exitfuncs(_PyRuntimeState *runtime)
{
- while (_PyRuntime.nexitfuncs > 0)
- (*_PyRuntime.exitfuncs[--_PyRuntime.nexitfuncs])();
+ while (runtime->nexitfuncs > 0) {
+ (*runtime->exitfuncs[--runtime->nexitfuncs])();
+ }
fflush(stdout);
fflush(stderr);
diff --git a/Python/pystate.c b/Python/pystate.c
index 6aaf993..498a954 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1078,10 +1078,11 @@ _PyGILState_GetInterpreterStateUnsafe(void)
}
void
-_PyGILState_Fini(void)
+_PyGILState_Fini(_PyRuntimeState *runtime)
{
- PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey);
- _PyRuntime.gilstate.autoInterpreterState = NULL;
+ struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
+ PyThread_tss_delete(&gilstate->autoTSSkey);
+ gilstate->autoInterpreterState = NULL;
}
/* Reset the TSS key - called by PyOS_AfterFork_Child().