File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -661,10 +661,6 @@ struct _warnings_runtime_state {
661661 PyObject * once_registry ; /* Dict */
662662 PyObject * default_action ; /* String */
663663 _PyRecursiveMutex lock ;
664- #ifdef HAVE_FORK
665- // Whether the thread calling fork() owns the warnings lock.
666- bool lock_held_at_fork ;
667- #endif
668664 long filters_version ;
669665 PyObject * context ;
670666};
Original file line number Diff line number Diff line change @@ -1693,6 +1693,11 @@ def test_fork_current_thread_holds_lock(self):
16931693 for _ in range(3):
16941694 _warnings._acquire_lock()
16951695 pid = os.fork()
1696+ if pid == 0:
1697+ # Ownership must also survive a second fork in the child.
1698+ child_pid = os.fork()
1699+ if child_pid != 0:
1700+ support.wait_process(child_pid, exitcode=0)
16961701 try:
16971702 # A warning must not change the inherited recursion depth.
16981703 warnings.warn('after fork')
Original file line number Diff line number Diff line change @@ -278,19 +278,24 @@ warnings_lock_held(WarningsState *st)
278278}
279279
280280#ifdef HAVE_FORK
281+ // PyOS_BeforeFork() holds HEAD_LOCK while saving this value and until fork(),
282+ // so concurrent forks cannot overwrite it before the child inherits it.
283+ // The child consumes its private copy before running Python callbacks.
284+ static bool warnings_lock_held_at_fork ;
285+
281286void
282287_PyWarnings_BeforeFork (PyInterpreterState * interp )
283288{
284289 WarningsState * st = warnings_get_state (interp );
285- st -> lock_held_at_fork = _PyRecursiveMutex_IsLockedByCurrentThread (& st -> lock );
290+ warnings_lock_held_at_fork = _PyRecursiveMutex_IsLockedByCurrentThread (& st -> lock );
286291}
287292
288293void
289294_PyWarnings_AfterFork (PyInterpreterState * interp )
290295{
291296 WarningsState * st = warnings_get_state (interp );
292- _PyRecursiveMutex_at_fork_reinit (& st -> lock , st -> lock_held_at_fork );
293- st -> lock_held_at_fork = false;
297+ _PyRecursiveMutex_at_fork_reinit (& st -> lock , warnings_lock_held_at_fork );
298+ warnings_lock_held_at_fork = false;
294299}
295300#endif
296301
Original file line number Diff line number Diff line change @@ -362,6 +362,7 @@ Objects/unicodeobject.c unicode_translate_call_errorhandler argparse -
362362Parser/parser.c - reserved_keywords -
363363Parser/parser.c - soft_keywords -
364364Parser/lexer/lexer.c - type_comment_prefix -
365+ Python/_warnings.c - warnings_lock_held_at_fork -
365366Python/ceval.c - _PyEval_BinaryOps -
366367Python/ceval.c - _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS -
367368Python/ceval.c - _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR -
You can’t perform that action at this time.
0 commit comments