clear_after_fork (#6933)

This commit is contained in:
Jeong, YunWon
2026-02-01 19:42:30 +09:00
committed by GitHub
parent 0b9c90fcc4
commit dd09f41dcc
4 changed files with 42 additions and 1 deletions

View File

@@ -197,6 +197,15 @@ mod weakref_lock {
core::hint::spin_loop();
}
}
/// Reset all weakref stripe locks after fork in child process.
/// Locks held by parent threads would cause infinite spin in the child.
#[cfg(unix)]
pub(crate) fn reset_all_after_fork() {
for lock in &LOCKS {
lock.store(0, Ordering::Release);
}
}
}
#[cfg(not(feature = "threading"))]
@@ -212,6 +221,13 @@ mod weakref_lock {
}
}
/// Reset weakref stripe locks after fork. Must be called before any
/// Python code runs in the child process.
#[cfg(all(unix, feature = "threading"))]
pub(crate) fn reset_weakref_locks_after_fork() {
weakref_lock::reset_all_after_fork();
}
// === WeakRefList: inline on every object (tp_weaklist) ===
pub(super) struct WeakRefList {

View File

@@ -50,6 +50,16 @@ pub(crate) fn set_triggered() {
ANY_TRIGGERED.store(true, Ordering::Release);
}
/// Reset all signal trigger state after fork in child process.
/// Stale triggers from the parent must not fire in the child.
#[cfg(unix)]
pub(crate) fn clear_after_fork() {
ANY_TRIGGERED.store(false, Ordering::Release);
for trigger in &TRIGGERS {
trigger.store(false, Ordering::Relaxed);
}
}
pub fn assert_in_range(signum: i32, vm: &VirtualMachine) -> PyResult<()> {
if (1..NSIG as i32).contains(&signum) {
Ok(())

View File

@@ -660,8 +660,16 @@ pub mod module {
}
fn py_os_after_fork_child(vm: &VirtualMachine) {
// Reset low-level state before any Python code runs in the child.
// Signal triggers from the parent must not fire in the child.
crate::signal::clear_after_fork();
crate::stdlib::signal::_signal::clear_wakeup_fd_after_fork();
// Reset weakref stripe locks that may have been held during fork.
#[cfg(feature = "threading")]
crate::object::reset_weakref_locks_after_fork();
// Mark all other threads as done before running Python callbacks
// See _PyThread_AfterFork behavior
#[cfg(feature = "threading")]
crate::stdlib::thread::after_fork_child(vm);

View File

@@ -679,6 +679,13 @@ pub(crate) mod _signal {
}
}
/// Reset wakeup fd after fork in child process.
/// The child must not write to the parent's wakeup fd.
#[cfg(unix)]
pub(crate) fn clear_wakeup_fd_after_fork() {
WAKEUP.store(INVALID_WAKEUP, Ordering::Relaxed);
}
pub(crate) fn module_exec(
vm: &VirtualMachine,
module: &Py<crate::builtins::PyModule>,