From f2bf9e198ea183f0a490f93caa3d43678c8fa0a1 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 24 Oct 2024 11:19:02 +0200 Subject: [PATCH] Add thread Builder::no_hooks(). --- library/std/src/thread/mod.rs | 22 +++++++++++++++++++--- library/std/src/thread/spawnhook.rs | 9 +++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 79621e7fa6b..4a4c2c4b960 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -264,6 +264,8 @@ pub struct Builder { name: Option, // The size of the stack for the spawned thread in bytes stack_size: Option, + // Skip running and inheriting the thread spawn hooks + no_hooks: bool, } impl Builder { @@ -287,7 +289,7 @@ impl Builder { /// ``` #[stable(feature = "rust1", since = "1.0.0")] 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 @@ -343,6 +345,16 @@ impl Builder { 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 /// [`io::Result`] to its [`JoinHandle`]. /// @@ -465,7 +477,7 @@ impl Builder { F: 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(|| { static MIN: AtomicUsize = AtomicUsize::new(0); @@ -491,7 +503,11 @@ impl Builder { 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(); diff --git a/library/std/src/thread/spawnhook.rs b/library/std/src/thread/spawnhook.rs index 9c4e9eb6aa1..b0732ae69c3 100644 --- a/library/std/src/thread/spawnhook.rs +++ b/library/std/src/thread/spawnhook.rs @@ -104,7 +104,7 @@ where /// Called on the parent 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. // (Increments the refcount to the first node.) 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, // which will then run SpawnHookResults::run(). - SpawnHookResults { hooks, to_run } + ChildSpawnHooks { hooks, to_run } } /// The results of running the spawn hooks. /// /// This struct is sent to the new thread. /// It contains the inherited hooks and the closures to be run. -pub(super) struct SpawnHookResults { +#[derive(Default)] +pub(super) struct ChildSpawnHooks { hooks: SpawnHooks, to_run: Vec>, } -impl SpawnHookResults { +impl ChildSpawnHooks { // This is run on the newly spawned thread, directly at the start. pub(super) fn run(self) { SPAWN_HOOKS.set(self.hooks);