Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ lto = "thin"
[patch.crates-io]
# REDOX START, Uncomment when you want to compile/check with redoxer
# REDOX END
# Fork-safety: expose reinit_after_fork() to reset global hash table after fork
parking_lot_core = { git = "https://github.com/youknowone/parking_lot", rev = "5953f33ea399365bd15fdd9b6aaf8bc5ad7c8e46" }

[package.metadata.packager]
product-name = "RustPython"
Expand Down Expand Up @@ -184,6 +186,7 @@ num_enum = { version = "0.7", default-features = false }
optional = "0.5"
once_cell = "1.20.3"
parking_lot = "0.12.3"
parking_lot_core = { version = "0.9.12" }
paste = "1.0.15"
proc-macro2 = "1.0.105"
pymath = { version = "0.1.5", features = ["mul_add", "malachite-bigint", "complex"] }
Expand Down
1 change: 1 addition & 0 deletions crates/vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ unic-ucd-category = { workspace = true }
unic-ucd-ident = { workspace = true }

[target.'cfg(unix)'.dependencies]
parking_lot_core = { workspace = true, features = ["fork"] }
rustix = { workspace = true }
nix = { workspace = true }
exitcode = "1.1.2"
Expand Down
20 changes: 6 additions & 14 deletions crates/vm/src/stdlib/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,9 @@ pub(crate) mod _thread {

#[pymethod]
fn _at_fork_reinit(&self, _vm: &VirtualMachine) -> PyResult<()> {
if self.mu.is_locked() {
unsafe {
self.mu.unlock();
};
}
// Casting to AtomicCell is as unsafe as CPython code.
// Using AtomicCell will prevent compiler optimizer move it to somewhere later unsafe place.
// It will be not under the cell anymore after init call.

// Don't call unlock() — it may invoke unlock_slow() which accesses
// parking_lot_core's global hash table that is stale after fork().
// Just overwrite the mutex with a fresh INIT value.
let new_mut = RawMutex::INIT;
unsafe {
let old_mutex: &AtomicCell<RawMutex> = core::mem::transmute(&self.mu);
Expand Down Expand Up @@ -247,11 +241,9 @@ pub(crate) mod _thread {

#[pymethod]
fn _at_fork_reinit(&self, _vm: &VirtualMachine) -> PyResult<()> {
if self.mu.is_locked() {
unsafe {
self.mu.unlock();
};
}
// Don't call unlock() — it may invoke unlock_slow() which accesses
// parking_lot_core's global hash table that is stale after fork().
// Just overwrite the mutex with a fresh INIT value.
self.count.store(0, core::sync::atomic::Ordering::Relaxed);
let new_mut = RawRMutex::INIT;
unsafe {
Expand Down
Loading