Skip to content

Commit

Permalink
[3.9] bpo-42540: reallocation of id_mutex should not force default al…
Browse files Browse the repository at this point in the history
…locator (GH-29564) (GH-29600)

Unlike the other locks reinitialized by _PyRuntimeState_ReInitThreads,
the "interpreters.main->id_mutex" is not freed by _PyRuntimeState_Fini
and should not force the default raw allocator..
(cherry picked from commit 736684b)

Co-authored-by: Sam Gross <colesbury@gmail.com>
  • Loading branch information
colesbury committed Nov 17, 2021
1 parent ac89f8c commit 87787c8
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
16 changes: 16 additions & 0 deletions Lib/test/test_os.py
Expand Up @@ -4273,6 +4273,22 @@ def test_times(self):
self.assertEqual(times.elapsed, 0)


@requires_os_func('fork')
class ForkTests(unittest.TestCase):
def test_fork(self):
# bpo-42540: ensure os.fork() with non-default memory allocator does
# not crash on exit.
code = """if 1:
import os
from test import support
pid = os.fork()
if pid != 0:
support.wait_process(pid, exitcode=0)
"""
assert_python_ok("-c", code)
assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")


# Only test if the C version is provided, otherwise TestPEP519 already tested
# the pure Python implementation.
if hasattr(os, "_fspath"):
Expand Down
@@ -0,0 +1,2 @@
Fix crash when :func:`os.fork` is called with an active non-default
memory allocator.
5 changes: 4 additions & 1 deletion Python/pystate.c
Expand Up @@ -139,11 +139,14 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

int interp_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.mutex);
int main_interp_id_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);
int xidregistry_mutex = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex);

PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

/* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does
* not force the default allocator. */
int main_interp_id_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);

if (interp_mutex < 0) {
Py_FatalError("Can't initialize lock for runtime interpreters");
}
Expand Down

0 comments on commit 87787c8

Please sign in to comment.