]> granicus.if.org Git - python/commitdiff
bpo-33005: Fix _PyGILState_Reinit() (GH-6001)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 6 Mar 2018 13:52:27 +0000 (05:52 -0800)
committerGitHub <noreply@github.com>
Tue, 6 Mar 2018 13:52:27 +0000 (05:52 -0800)
Fix a crash on fork when using a custom memory allocator (ex: using
PYTHONMALLOC env var).

_PyGILState_Reinit() and _PyInterpreterState_Enable() now use the
default RAW memory allocator to allocate a new interpreters mutex on
fork.
(cherry picked from commit 5d92647102fac9e116b98ab8bbc632eeed501c34)

Co-authored-by: Victor Stinner <victor.stinner@gmail.com>
Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst [new file with mode: 0644]
Python/pystate.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst
new file mode 100644 (file)
index 0000000..6c8b99c
--- /dev/null
@@ -0,0 +1,4 @@
+Fix a crash on fork when using a custom memory allocator (ex: using
+PYTHONMALLOC env var). _PyGILState_Reinit() and _PyInterpreterState_Enable()
+now use the default RAW memory allocator to allocate a new interpreters mutex
+on fork.
index a87801f5692242bb4045704af8720b9503bffad4..140d2fba8efd3de7b92fd938f1d7f7e1e40f27fc 100644 (file)
@@ -103,15 +103,24 @@ _PyInitError
 _PyInterpreterState_Enable(_PyRuntimeState *runtime)
 {
     runtime->interpreters.next_id = 0;
-    /* Since we only call _PyRuntimeState_Init() once per process
-       (see _PyRuntime_Initialize()), we make sure the mutex is
-       initialized here. */
+
+    /* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex.
+       Create a new mutex if needed. */
     if (runtime->interpreters.mutex == NULL) {
+        /* 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();
+
+        PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
         if (runtime->interpreters.mutex == NULL) {
             return _Py_INIT_ERR("Can't initialize threads for interpreter");
         }
     }
+
     return _Py_INIT_OK();
 }
 
@@ -933,9 +942,19 @@ _PyGILState_Fini(void)
 void
 _PyGILState_Reinit(void)
 {
+    /* 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();
-    if (_PyRuntime.interpreters.mutex == NULL)
+
+    PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+    if (_PyRuntime.interpreters.mutex == NULL) {
         Py_FatalError("Can't initialize threads for interpreter");
+    }
+
     PyThreadState *tstate = PyGILState_GetThisThreadState();
     PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey);
     if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) {