]> granicus.if.org Git - python/commitdiff
bpo-36710: Add runtime variable to Py_FinalizeEx() (GH-12937)
authorVictor Stinner <vstinner@redhat.com>
Wed, 24 Apr 2019 15:24:01 +0000 (17:24 +0200)
committerGitHub <noreply@github.com>
Wed, 24 Apr 2019 15:24:01 +0000 (17:24 +0200)
* 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()

Include/internal/pycore_pylifecycle.h
Modules/gcmodule.c
Python/pylifecycle.c
Python/pystate.c

index bfff24b80a9fe1e1fd97319b74ddb6386d69b3dc..f07bc427bb88a3bac6399118d6e04c8c252c1969 100644 (file)
@@ -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);
 
index a75d5fed95f11e80a491834c0ef4ac090cb99f0e..f36c7f5d5e409e2b0d081ceaefb8d97c974f5535 100644 (file)
@@ -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 */
index c7920ef6262d3c509f4d648f9076042edafb5a59..fe4cb97a4740f17ab1b40cdbab1fb82b9d18013d 100644 (file)
@@ -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);
index 6aaf993cfe2cd241f4d8b2c17dc26fcf32acfa24..498a9546e1b8cc34cd50dfd5a814d9cd973e9200 100644 (file)
@@ -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().