diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2018-03-06 13:31:37 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-06 13:31:37 (GMT) |
commit | 5d92647102fac9e116b98ab8bbc632eeed501c34 (patch) | |
tree | b8fbf9c599294d1497a2bbcfa004d27d0c7ad5e0 | |
parent | efd2bac1564f8141a4eab1bf8779b412974b8d69 (diff) | |
download | cpython-5d92647102fac9e116b98ab8bbc632eeed501c34.zip cpython-5d92647102fac9e116b98ab8bbc632eeed501c34.tar.gz cpython-5d92647102fac9e116b98ab8bbc632eeed501c34.tar.bz2 |
bpo-33005: Fix _PyGILState_Reinit() (#6001)
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.
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst | 4 | ||||
-rw-r--r-- | Python/pystate.c | 27 |
2 files changed, 27 insertions, 4 deletions
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 index 0000000..6c8b99c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst @@ -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. diff --git a/Python/pystate.c b/Python/pystate.c index a87801f..140d2fb 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -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) { |