Add thread Builder::no_hooks().

This commit is contained in:
Mara Bos 2024-10-24 11:19:02 +02:00
parent 947354fbec
commit f2bf9e198e
2 changed files with 24 additions and 7 deletions

View File

@ -264,6 +264,8 @@ pub struct Builder {
name: Option<String>, name: Option<String>,
// The size of the stack for the spawned thread in bytes // The size of the stack for the spawned thread in bytes
stack_size: Option<usize>, stack_size: Option<usize>,
// Skip running and inheriting the thread spawn hooks
no_hooks: bool,
} }
impl Builder { impl Builder {
@ -287,7 +289,7 @@ impl Builder {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> Builder { pub fn new() -> Builder {
Builder { name: None, stack_size: None } Builder { name: None, stack_size: None, no_hooks: false }
} }
/// Names the thread-to-be. Currently the name is used for identification /// Names the thread-to-be. Currently the name is used for identification
@ -343,6 +345,16 @@ impl Builder {
self self
} }
/// Disables running and inheriting [spawn hooks](add_spawn_hook).
///
/// Use this if the parent thread is in no way relevant for the child thread.
/// For example, when lazily spawning threads for a thread pool.
#[unstable(feature = "thread_spawn_hook", issue = "none")]
pub fn no_hooks(mut self) -> Builder {
self.no_hooks = true;
self
}
/// Spawns a new thread by taking ownership of the `Builder`, and returns an /// Spawns a new thread by taking ownership of the `Builder`, and returns an
/// [`io::Result`] to its [`JoinHandle`]. /// [`io::Result`] to its [`JoinHandle`].
/// ///
@ -465,7 +477,7 @@ impl Builder {
F: Send, F: Send,
T: Send, T: Send,
{ {
let Builder { name, stack_size } = self; let Builder { name, stack_size, no_hooks } = self;
let stack_size = stack_size.unwrap_or_else(|| { let stack_size = stack_size.unwrap_or_else(|| {
static MIN: AtomicUsize = AtomicUsize::new(0); static MIN: AtomicUsize = AtomicUsize::new(0);
@ -491,7 +503,11 @@ impl Builder {
None => Thread::new_unnamed(id), None => Thread::new_unnamed(id),
}; };
let hooks = spawnhook::run_spawn_hooks(&my_thread); let hooks = if no_hooks {
spawnhook::ChildSpawnHooks::default()
} else {
spawnhook::run_spawn_hooks(&my_thread)
};
let their_thread = my_thread.clone(); let their_thread = my_thread.clone();

View File

@ -104,7 +104,7 @@ where
/// Called on the parent thread. /// Called on the parent thread.
/// ///
/// Returns the functions to be called on the newly spawned thread. /// Returns the functions to be called on the newly spawned thread.
pub(super) fn run_spawn_hooks(thread: &Thread) -> SpawnHookResults { pub(super) fn run_spawn_hooks(thread: &Thread) -> ChildSpawnHooks {
// Get a snapshot of the spawn hooks. // Get a snapshot of the spawn hooks.
// (Increments the refcount to the first node.) // (Increments the refcount to the first node.)
let hooks = SPAWN_HOOKS.with(|hooks| { let hooks = SPAWN_HOOKS.with(|hooks| {
@ -121,19 +121,20 @@ pub(super) fn run_spawn_hooks(thread: &Thread) -> SpawnHookResults {
} }
// Pass on the snapshot of the hooks and the results to the new thread, // Pass on the snapshot of the hooks and the results to the new thread,
// which will then run SpawnHookResults::run(). // which will then run SpawnHookResults::run().
SpawnHookResults { hooks, to_run } ChildSpawnHooks { hooks, to_run }
} }
/// The results of running the spawn hooks. /// The results of running the spawn hooks.
/// ///
/// This struct is sent to the new thread. /// This struct is sent to the new thread.
/// It contains the inherited hooks and the closures to be run. /// It contains the inherited hooks and the closures to be run.
pub(super) struct SpawnHookResults { #[derive(Default)]
pub(super) struct ChildSpawnHooks {
hooks: SpawnHooks, hooks: SpawnHooks,
to_run: Vec<Box<dyn FnOnce() + Send>>, to_run: Vec<Box<dyn FnOnce() + Send>>,
} }
impl SpawnHookResults { impl ChildSpawnHooks {
// This is run on the newly spawned thread, directly at the start. // This is run on the newly spawned thread, directly at the start.
pub(super) fn run(self) { pub(super) fn run(self) {
SPAWN_HOOKS.set(self.hooks); SPAWN_HOOKS.set(self.hooks);