mirror of
https://github.com/python/cpython.git
synced 2025-10-02 05:12:23 +00:00
bpo-33005: Fix _PyGILState_Reinit() (GH-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.
(cherry picked from commit 5d92647102
)
Co-authored-by: Victor Stinner <victor.stinner@gmail.com>
This commit is contained in:
parent
96fdbacb77
commit
31e2b76f7b
2 changed files with 27 additions and 4 deletions
|
@ -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.
|
|
@ -103,15 +103,24 @@ _PyInitError
|
||||||
_PyInterpreterState_Enable(_PyRuntimeState *runtime)
|
_PyInterpreterState_Enable(_PyRuntimeState *runtime)
|
||||||
{
|
{
|
||||||
runtime->interpreters.next_id = 0;
|
runtime->interpreters.next_id = 0;
|
||||||
/* Since we only call _PyRuntimeState_Init() once per process
|
|
||||||
(see _PyRuntime_Initialize()), we make sure the mutex is
|
/* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex.
|
||||||
initialized here. */
|
Create a new mutex if needed. */
|
||||||
if (runtime->interpreters.mutex == NULL) {
|
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();
|
runtime->interpreters.mutex = PyThread_allocate_lock();
|
||||||
|
|
||||||
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
if (runtime->interpreters.mutex == NULL) {
|
if (runtime->interpreters.mutex == NULL) {
|
||||||
return _Py_INIT_ERR("Can't initialize threads for interpreter");
|
return _Py_INIT_ERR("Can't initialize threads for interpreter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _Py_INIT_OK();
|
return _Py_INIT_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -933,9 +942,19 @@ _PyGILState_Fini(void)
|
||||||
void
|
void
|
||||||
_PyGILState_Reinit(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();
|
_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");
|
Py_FatalError("Can't initialize threads for interpreter");
|
||||||
|
}
|
||||||
|
|
||||||
PyThreadState *tstate = PyGILState_GetThisThreadState();
|
PyThreadState *tstate = PyGILState_GetThisThreadState();
|
||||||
PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey);
|
PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey);
|
||||||
if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) {
|
if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue