-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move `fork` from origin to c-scape, and convert it back to using `unsafe extern "C" fn()` hooks instead of safe boxed closures. See bytecodealliance/rustix#137 for discussion. Add an at_thread_exit_raw to origin, which allows thread destructors to be registered without allocating, which is important since Rust will register TLS destructors while threads are being constructed, before parking_lot is prepared for the global allocator to take locks. Update to the latest rustix, and the change from a safe execve to an unsafe raw execveat. This similarly allows it to avoid allocating, which is important as it's primarily called in the child of `fork`. And switch to a branch of parking_lot with changes to allow parking_lot locks to be used from within global allocator implementations. These changes allow us to move the `#[global_allocator]` back to the mustang crate, and restore the wee_alloc allocator option. More generally, origin and c-scape should in theory now work with any global allocator implementation.
- Loading branch information
1 parent
d47569c
commit aced4d4
Showing
13 changed files
with
329 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use std::env::var; | ||
use std::io::Write; | ||
|
||
fn main() { | ||
// Don't rerun this on changes other than build.rs, as we only depend on | ||
// the rustc version. | ||
println!("cargo:rerun-if-changed=build.rs"); | ||
|
||
use_feature_or_nothing("thread_local_const_init"); | ||
} | ||
|
||
fn use_feature_or_nothing(feature: &str) { | ||
if has_feature(feature) { | ||
use_feature(feature); | ||
} | ||
} | ||
|
||
fn use_feature(feature: &str) { | ||
println!("cargo:rustc-cfg={}", feature); | ||
} | ||
|
||
/// Test whether the rustc at `var("RUSTC")` supports the given feature. | ||
fn has_feature(feature: &str) -> bool { | ||
let out_dir = var("OUT_DIR").unwrap(); | ||
let rustc = var("RUSTC").unwrap(); | ||
|
||
let mut child = std::process::Command::new(rustc) | ||
.arg("--crate-type=rlib") // Don't require `main`. | ||
.arg("--emit=metadata") // Do as little as possible but still parse. | ||
.arg("--out-dir") | ||
.arg(out_dir) // Put the output somewhere inconsequential. | ||
.arg("-") // Read from stdin. | ||
.stdin(std::process::Stdio::piped()) // Stdin is a pipe. | ||
.spawn() | ||
.unwrap(); | ||
|
||
writeln!(child.stdin.take().unwrap(), "#![feature({})]", feature).unwrap(); | ||
|
||
child.wait().unwrap().success() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
use parking_lot::lock_api::RawMutex as _; | ||
use parking_lot::{Mutex, RawMutex}; | ||
|
||
/// Functions registered with `at_fork`. | ||
static FORK_FUNCS: Mutex<RegisteredForkFuncs> = | ||
Mutex::const_new(RawMutex::INIT, RegisteredForkFuncs::new()); | ||
|
||
/// A type for holding `fork` callbacks. | ||
#[derive(Default)] | ||
struct RegisteredForkFuncs { | ||
/// Functions called before calling `fork`. | ||
pub(crate) prepare: Vec<unsafe extern "C" fn()>, | ||
|
||
/// Functions called after calling `fork`, in the parent. | ||
pub(crate) parent: Vec<unsafe extern "C" fn()>, | ||
|
||
/// Functions called after calling `fork`, in the child. | ||
pub(crate) child: Vec<unsafe extern "C" fn()>, | ||
} | ||
|
||
impl RegisteredForkFuncs { | ||
pub(crate) const fn new() -> Self { | ||
Self { | ||
prepare: Vec::new(), | ||
parent: Vec::new(), | ||
child: Vec::new(), | ||
} | ||
} | ||
} | ||
|
||
/// Register functions to be called when `fork` is called. | ||
/// | ||
/// The handlers for each phase are called in the following order: | ||
/// the prepare handlers are called in reverse order of registration; | ||
/// the parent and child handlers are called in the order of registration. | ||
pub(crate) fn at_fork( | ||
prepare_func: Option<unsafe extern "C" fn()>, | ||
parent_func: Option<unsafe extern "C" fn()>, | ||
child_func: Option<unsafe extern "C" fn()>, | ||
) { | ||
let mut funcs = FORK_FUNCS.lock(); | ||
|
||
// Add the callbacks to the lists. | ||
funcs.prepare.extend(prepare_func); | ||
funcs.parent.extend(parent_func); | ||
funcs.child.extend(child_func); | ||
} | ||
|
||
pub(crate) unsafe fn fork() -> rustix::io::Result<Option<rustix::process::Pid>> { | ||
let funcs = FORK_FUNCS.lock(); | ||
|
||
// Callbacks before calling `fork`. | ||
funcs.prepare.iter().rev().for_each(|func| func()); | ||
|
||
// Call `fork`. | ||
match rustix::runtime::fork()? { | ||
None => { | ||
// The child's thread record is copied from the parent; | ||
// update it with the child's current-thread-id. | ||
#[cfg(feature = "threads")] | ||
origin::set_current_thread_id_after_a_fork(rustix::thread::gettid()); | ||
|
||
// Callbacks after calling `fork`, in the child. | ||
funcs.child.iter().for_each(|func| func()); | ||
Ok(None) | ||
} | ||
Some(pid) => { | ||
// Callbacks after calling `fork`, in the parent. | ||
funcs.parent.iter().for_each(|func| func()); | ||
Ok(Some(pid)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.