Skip to content

Commit 33f1674

Browse files
committed
Add "fork" feature flag (off by default)
1 parent 2266ba7 commit 33f1674

File tree

17 files changed

+86
-77
lines changed

17 files changed

+86
-77
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ flame-it = ["rustpython-vm/flame-it", "rustpython-stdlib/flame-it", "flame", "fl
2020
freeze-stdlib = ["stdlib", "rustpython-vm/freeze-stdlib", "rustpython-pylib?/freeze-stdlib"]
2121
jit = ["rustpython-vm/jit"]
2222
threading = ["rustpython-vm/threading", "rustpython-stdlib/threading"]
23+
fork = ["rustpython-vm/fork", "rustpython-stdlib/fork"]
2324
sqlite = ["rustpython-stdlib/sqlite"]
2425
ssl = []
2526
ssl-rustls = ["ssl", "rustpython-stdlib/ssl-rustls"]

crates/stdlib/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ default = ["compiler", "host_env"]
1515
host_env = ["rustpython-vm/host_env"]
1616
compiler = ["rustpython-vm/compiler"]
1717
threading = ["rustpython-common/threading", "rustpython-vm/threading"]
18+
fork = ["rustpython-vm/fork"]
1819
sqlite = ["dep:libsqlite3-sys"]
1920
# SSL backends - default to rustls
2021
ssl = []

crates/stdlib/src/_asyncio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub(crate) mod _asyncio {
4848
});
4949

5050
// Register fork handler to clear task state in child process
51-
#[cfg(unix)]
51+
#[cfg(feature = "fork")]
5252
{
5353
let on_fork = vm
5454
.get_attribute_opt(module.to_owned().into(), vm.ctx.intern_str("_on_fork"))?

crates/vm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ flame-it = ["flame", "flamer"]
2020
freeze-stdlib = ["encodings"]
2121
jit = ["rustpython-jit"]
2222
threading = ["rustpython-common/threading"]
23+
fork = ["threading"]
2324
gc = []
2425
compiler = ["parser", "codegen", "rustpython-compiler"]
2526
ast = ["ruff_python_ast", "ruff_text_size"]

crates/vm/src/codecs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ impl CodecsRegistry {
158158
/// # Safety
159159
/// Must only be called after fork() in the child process when no other
160160
/// threads exist.
161-
#[cfg(all(unix, feature = "threading"))]
161+
#[cfg(feature = "fork")]
162162
pub(crate) unsafe fn reinit_after_fork(&self) {
163163
unsafe { crate::common::lock::reinit_rwlock_after_fork(&self.inner) };
164164
}

crates/vm/src/gc_state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl GcGeneration {
9292
/// # Safety
9393
/// Must only be called after fork() in the child process when no other
9494
/// threads exist.
95-
#[cfg(all(unix, feature = "threading"))]
95+
#[cfg(feature = "fork")]
9696
unsafe fn reinit_stats_after_fork(&self) {
9797
unsafe { crate::common::lock::reinit_mutex_after_fork(&self.stats) };
9898
}
@@ -731,7 +731,7 @@ impl GcState {
731731
/// # Safety
732732
/// Must only be called after fork() in the child process when no other
733733
/// threads exist. The calling thread must NOT hold any of these locks.
734-
#[cfg(all(unix, feature = "threading"))]
734+
#[cfg(feature = "fork")]
735735
pub unsafe fn reinit_after_fork(&self) {
736736
use crate::common::lock::{reinit_mutex_after_fork, reinit_rwlock_after_fork};
737737

crates/vm/src/intern.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl StringPool {
3636
/// # Safety
3737
/// Must only be called after fork() in the child process when no other
3838
/// threads exist.
39-
#[cfg(all(unix, feature = "threading"))]
39+
#[cfg(feature = "fork")]
4040
pub(crate) unsafe fn reinit_after_fork(&self) {
4141
unsafe { crate::common::lock::reinit_rwlock_after_fork(&self.inner) };
4242
}

crates/vm/src/object/core.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ mod weakref_lock {
470470

471471
/// Reset all weakref stripe locks after fork in child process.
472472
/// Locks held by parent threads would cause infinite spin in the child.
473-
#[cfg(unix)]
473+
#[cfg(feature = "fork")]
474474
pub(crate) fn reset_all_after_fork() {
475475
for lock in &LOCKS {
476476
lock.store(0, Ordering::Release);
@@ -493,7 +493,7 @@ mod weakref_lock {
493493

494494
/// Reset weakref stripe locks after fork. Must be called before any
495495
/// Python code runs in the child process.
496-
#[cfg(all(unix, feature = "threading"))]
496+
#[cfg(feature = "fork")]
497497
pub(crate) fn reset_weakref_locks_after_fork() {
498498
weakref_lock::reset_all_after_fork();
499499
}

crates/vm/src/signal.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,7 @@ pub(crate) fn is_triggered() -> bool {
9898

9999
/// Reset all signal trigger state after fork in child process.
100100
/// Stale triggers from the parent must not fire in the child.
101-
#[cfg(unix)]
102-
#[cfg(feature = "host_env")]
101+
#[cfg(feature = "fork")]
103102
pub(crate) fn clear_after_fork() {
104103
ANY_TRIGGERED.store(false, Ordering::Release);
105104
for trigger in &TRIGGERS {

crates/vm/src/stdlib/imp.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ mod lock {
3838
IMP_LOCK.lock();
3939
}
4040

41+
#[cfg(feature = "fork")]
4142
pub(super) fn release_lock_after_fork_parent() {
4243
if IMP_LOCK.is_locked() && IMP_LOCK.is_owned_by_current_thread() {
4344
unsafe { IMP_LOCK.unlock() };
@@ -53,7 +54,7 @@ mod lock {
5354
/// # Safety
5455
///
5556
/// Must only be called from single-threaded child after fork().
56-
#[cfg(unix)]
57+
#[cfg(feature = "fork")]
5758
pub(crate) unsafe fn reinit_after_fork() {
5859
if IMP_LOCK.is_locked() && !IMP_LOCK.is_owned_by_current_thread() {
5960
// Held by a dead thread — reset to unlocked.
@@ -65,7 +66,7 @@ mod lock {
6566
/// behavior in the post-fork child:
6667
/// 1) if ownership metadata is stale (dead owner / changed tid), reset;
6768
/// 2) if current thread owns the lock, release it.
68-
#[cfg(unix)]
69+
#[cfg(feature = "fork")]
6970
pub(super) unsafe fn after_fork_child_reinit_and_release() {
7071
unsafe { reinit_after_fork() };
7172
if IMP_LOCK.is_locked() && IMP_LOCK.is_owned_by_current_thread() {
@@ -75,22 +76,22 @@ mod lock {
7576
}
7677

7778
/// Re-export for fork safety code in posix.rs
78-
#[cfg(feature = "threading")]
79+
#[cfg(feature = "fork")]
7980
pub(crate) fn acquire_imp_lock_for_fork() {
8081
lock::acquire_lock_for_fork();
8182
}
8283

83-
#[cfg(feature = "threading")]
84+
#[cfg(feature = "fork")]
8485
pub(crate) fn release_imp_lock_after_fork_parent() {
8586
lock::release_lock_after_fork_parent();
8687
}
8788

88-
#[cfg(all(unix, feature = "threading"))]
89+
#[cfg(feature = "fork")]
8990
pub(crate) unsafe fn reinit_imp_lock_after_fork() {
9091
unsafe { lock::reinit_after_fork() }
9192
}
9293

93-
#[cfg(all(unix, feature = "threading"))]
94+
#[cfg(feature = "fork")]
9495
pub(crate) unsafe fn after_fork_child_imp_lock_release() {
9596
unsafe { lock::after_fork_child_reinit_and_release() }
9697
}

0 commit comments

Comments
 (0)