From 69162aacbd87e850b4f4919e9e492247b2e58903 Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Wed, 18 Feb 2026 18:45:18 +0100 Subject: [PATCH 01/19] add name API to runtime builder --- tokio/src/runtime/builder.rs | 31 +++++++++++++++++++ tokio/src/runtime/handle.rs | 22 +++++++++++++ .../runtime/scheduler/current_thread/mod.rs | 10 ++++++ .../runtime/scheduler/multi_thread/handle.rs | 7 +++++ .../src/runtime/scheduler/multi_thread/mod.rs | 2 ++ .../runtime/scheduler/multi_thread/worker.rs | 2 ++ 6 files changed, 74 insertions(+) diff --git a/tokio/src/runtime/builder.rs b/tokio/src/runtime/builder.rs index e50b337635a..171a8e51dd7 100644 --- a/tokio/src/runtime/builder.rs +++ b/tokio/src/runtime/builder.rs @@ -75,6 +75,9 @@ pub struct Builder { /// Name fn used for threads spawned by the runtime. pub(super) thread_name: ThreadNameFn, + /// Name used for the runtime. + name: String, //TODO(5545): should this be a slice instead? + /// Stack size used for threads spawned by the runtime. pub(super) thread_stack_size: Option, @@ -290,6 +293,9 @@ impl Builder { // Default thread name thread_name: std::sync::Arc::new(|| "tokio-rt-worker".into()), + // Default runtime name + name: String::from("tokio-rt"), + // Do not set a stack size by default thread_stack_size: None, @@ -538,6 +544,29 @@ impl Builder { self } + + /// Sets name of the runtime. + /// + /// # Examples + /// + /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { + /// # use tokio::runtime; + /// + /// # pub fn main() { + /// let rt = runtime::Builder::new_multi_thread() + /// .runtime("my-runtime") + /// .build(); + /// # } + /// # } + /// ``` + pub fn name(&mut self, val: impl Into) -> &mut Self { + let val = val.into(); + self.name = val; + self + } + /// Sets a function used to generate the name of threads spawned by the `Runtime`'s thread pool. /// /// The default name fn is `|| "tokio-rt-worker".into()`. @@ -1633,6 +1662,7 @@ impl Builder { metrics_poll_count_histogram: self.metrics_poll_count_histogram_builder(), }, local_tid, + self.name.clone(), ); let handle = Handle { @@ -1814,6 +1844,7 @@ cfg_rt_multi_thread! { metrics_poll_count_histogram: self.metrics_poll_count_histogram_builder(), }, self.timer_flavor, + self.name.clone(), ); let handle = Handle { inner: scheduler::Handle::MultiThread(handle) }; diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index 612bcd2c059..bceea1bf6d8 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -474,6 +474,28 @@ impl Handle { runtime::Id::new(owned_id) } + /// Returns the name of the current `Runtime`. + /// + /// # Examples + /// + /// ``` + /// use tokio::runtime::Handle; + /// + /// #[tokio::main(flavor = "current_thread")] + /// async fn main() { + /// println!("Current runtime id: {}", Handle::current().name(); + /// } + /// ``` + /// + /// [`Id`]: struct@crate::runtime::Id + pub fn name(&self) -> String { + match &self.inner { + scheduler::Handle::CurrentThread(handle) => handle.runtime_name(), + #[cfg(feature = "rt-multi-thread")] + scheduler::Handle::MultiThread(handle) => handle.runtime_name(), + } + } + /// Returns a view that lets you get information about how the runtime /// is performing. pub fn metrics(&self) -> RuntimeMetrics { diff --git a/tokio/src/runtime/scheduler/current_thread/mod.rs b/tokio/src/runtime/scheduler/current_thread/mod.rs index 68ab17f1402..4562fd70fb8 100644 --- a/tokio/src/runtime/scheduler/current_thread/mod.rs +++ b/tokio/src/runtime/scheduler/current_thread/mod.rs @@ -34,6 +34,10 @@ pub(crate) struct CurrentThread { /// Handle to the current thread scheduler pub(crate) struct Handle { + + /// The name of runtime + pub(crate) runtime_name: String, + /// Scheduler state shared across threads shared: Shared, @@ -132,6 +136,7 @@ impl CurrentThread { seed_generator: RngSeedGenerator, config: Config, local_tid: Option, + runtime_name: String, ) -> (CurrentThread, Arc) { let worker_metrics = WorkerMetrics::from_config(&config); worker_metrics.set_thread_id(thread::current().id()); @@ -142,6 +147,7 @@ impl CurrentThread { .unwrap_or(DEFAULT_GLOBAL_QUEUE_INTERVAL); let handle = Arc::new(Handle { + runtime_name, task_hooks: TaskHooks { task_spawn_callback: config.before_spawn.clone(), task_terminate_callback: config.after_termination.clone(), @@ -639,6 +645,10 @@ impl Handle { pub(crate) fn owned_id(&self) -> NonZeroU64 { self.shared.owned.id } + + pub(crate) fn runtime_name(&self) -> String { + self.runtime_name.clone() + } } impl fmt::Debug for Handle { diff --git a/tokio/src/runtime/scheduler/multi_thread/handle.rs b/tokio/src/runtime/scheduler/multi_thread/handle.rs index 3d4226c4017..752ac422072 100644 --- a/tokio/src/runtime/scheduler/multi_thread/handle.rs +++ b/tokio/src/runtime/scheduler/multi_thread/handle.rs @@ -23,6 +23,9 @@ use crate::loom::sync::atomic::{AtomicBool, Ordering::SeqCst}; /// Handle to the multi thread scheduler pub(crate) struct Handle { + /// + pub(crate) runtime_name: String, + /// Task spawner pub(super) shared: worker::Shared, @@ -123,6 +126,10 @@ impl Handle { pub(crate) fn owned_id(&self) -> NonZeroU64 { self.shared.owned.id } + + pub(crate) fn runtime_name(&self) -> String { + self.runtime_name.clone() + } } impl fmt::Debug for Handle { diff --git a/tokio/src/runtime/scheduler/multi_thread/mod.rs b/tokio/src/runtime/scheduler/multi_thread/mod.rs index 1c5e1a88884..1881705f149 100644 --- a/tokio/src/runtime/scheduler/multi_thread/mod.rs +++ b/tokio/src/runtime/scheduler/multi_thread/mod.rs @@ -62,6 +62,7 @@ impl MultiThread { seed_generator: RngSeedGenerator, config: Config, timer_flavor: TimerFlavor, + runtime_name: String, ) -> (MultiThread, Arc, Launch) { let parker = Parker::new(driver); let (handle, launch) = worker::create( @@ -72,6 +73,7 @@ impl MultiThread { seed_generator, config, timer_flavor, + runtime_name, ); (MultiThread, handle, launch) diff --git a/tokio/src/runtime/scheduler/multi_thread/worker.rs b/tokio/src/runtime/scheduler/multi_thread/worker.rs index f48e6ba5271..582f7b3a1fe 100644 --- a/tokio/src/runtime/scheduler/multi_thread/worker.rs +++ b/tokio/src/runtime/scheduler/multi_thread/worker.rs @@ -262,6 +262,7 @@ pub(super) fn create( seed_generator: RngSeedGenerator, config: Config, timer_flavor: TimerFlavor, + runtime_name: String, ) -> (Arc, Launch) { let mut cores = Vec::with_capacity(size); let mut remotes = Vec::with_capacity(size); @@ -301,6 +302,7 @@ pub(super) fn create( let remotes_len = remotes.len(); let handle = Arc::new(Handle { + runtime_name: runtime_name, task_hooks: TaskHooks::from_config(&config), shared: Shared { remotes: remotes.into_boxed_slice(), From 49628202cec171301bd3b5e865b670bf8c274122 Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Wed, 18 Feb 2026 18:52:44 +0100 Subject: [PATCH 02/19] add a todo --- tokio/src/runtime/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio/src/runtime/builder.rs b/tokio/src/runtime/builder.rs index 171a8e51dd7..67ffa31b69b 100644 --- a/tokio/src/runtime/builder.rs +++ b/tokio/src/runtime/builder.rs @@ -561,7 +561,7 @@ impl Builder { /// # } /// # } /// ``` - pub fn name(&mut self, val: impl Into) -> &mut Self { + pub fn name(&mut self, val: impl Into) -> &mut Self { //TODO(5545): should this be an unstable API? let val = val.into(); self.name = val; self From 1b8b5f141f9350ca85fbe29fc7bd11ee6c7e196f Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 08:00:15 +0100 Subject: [PATCH 03/19] fix example name --- tokio/src/runtime/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio/src/runtime/builder.rs b/tokio/src/runtime/builder.rs index 67ffa31b69b..2a9fe0361ab 100644 --- a/tokio/src/runtime/builder.rs +++ b/tokio/src/runtime/builder.rs @@ -556,7 +556,7 @@ impl Builder { /// /// # pub fn main() { /// let rt = runtime::Builder::new_multi_thread() - /// .runtime("my-runtime") + /// .name("my-runtime") /// .build(); /// # } /// # } From bc203fee1e43dc0ef1aeb4e207a8c723bb82a98a Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 16:14:13 +0100 Subject: [PATCH 04/19] improve return references --- tokio/src/runtime/builder.rs | 17 ++++++++--------- tokio/src/runtime/handle.rs | 8 ++++---- .../src/runtime/scheduler/current_thread/mod.rs | 10 +++++----- .../runtime/scheduler/multi_thread/handle.rs | 8 ++++---- tokio/src/runtime/scheduler/multi_thread/mod.rs | 4 ++-- .../runtime/scheduler/multi_thread/worker.rs | 4 ++-- 6 files changed, 25 insertions(+), 26 deletions(-) diff --git a/tokio/src/runtime/builder.rs b/tokio/src/runtime/builder.rs index 2a9fe0361ab..3dbb1da41e7 100644 --- a/tokio/src/runtime/builder.rs +++ b/tokio/src/runtime/builder.rs @@ -54,6 +54,9 @@ pub struct Builder { /// Runtime type kind: Kind, + /// Name used for the runtime. + name: Option, + /// Whether or not to enable the I/O driver enable_io: bool, nevents: usize, @@ -75,9 +78,6 @@ pub struct Builder { /// Name fn used for threads spawned by the runtime. pub(super) thread_name: ThreadNameFn, - /// Name used for the runtime. - name: String, //TODO(5545): should this be a slice instead? - /// Stack size used for threads spawned by the runtime. pub(super) thread_stack_size: Option, @@ -274,6 +274,9 @@ impl Builder { Builder { kind, + // Default runtime name + name: None, + // I/O defaults to "off" enable_io: false, nevents: 1024, @@ -293,9 +296,6 @@ impl Builder { // Default thread name thread_name: std::sync::Arc::new(|| "tokio-rt-worker".into()), - // Default runtime name - name: String::from("tokio-rt"), - // Do not set a stack size by default thread_stack_size: None, @@ -544,7 +544,6 @@ impl Builder { self } - /// Sets name of the runtime. /// /// # Examples @@ -561,9 +560,9 @@ impl Builder { /// # } /// # } /// ``` - pub fn name(&mut self, val: impl Into) -> &mut Self { //TODO(5545): should this be an unstable API? + pub fn name(&mut self, val: impl Into) -> &mut Self { let val = val.into(); - self.name = val; + self.name = Some(val); self } diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index bceea1bf6d8..5ef565bf646 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -483,16 +483,16 @@ impl Handle { /// /// #[tokio::main(flavor = "current_thread")] /// async fn main() { - /// println!("Current runtime id: {}", Handle::current().name(); + /// println!("Current runtime id: {}", Handle::current().name().unwrap(); /// } /// ``` /// /// [`Id`]: struct@crate::runtime::Id - pub fn name(&self) -> String { + pub fn name(&self) -> Option<&str> { match &self.inner { - scheduler::Handle::CurrentThread(handle) => handle.runtime_name(), + scheduler::Handle::CurrentThread(handle) => handle.name(), #[cfg(feature = "rt-multi-thread")] - scheduler::Handle::MultiThread(handle) => handle.runtime_name(), + scheduler::Handle::MultiThread(handle) => handle.name(), } } diff --git a/tokio/src/runtime/scheduler/current_thread/mod.rs b/tokio/src/runtime/scheduler/current_thread/mod.rs index 4562fd70fb8..dd7c6fa3010 100644 --- a/tokio/src/runtime/scheduler/current_thread/mod.rs +++ b/tokio/src/runtime/scheduler/current_thread/mod.rs @@ -36,7 +36,7 @@ pub(crate) struct CurrentThread { pub(crate) struct Handle { /// The name of runtime - pub(crate) runtime_name: String, + pub(crate) name: Option, /// Scheduler state shared across threads shared: Shared, @@ -136,7 +136,7 @@ impl CurrentThread { seed_generator: RngSeedGenerator, config: Config, local_tid: Option, - runtime_name: String, + name: Option, ) -> (CurrentThread, Arc) { let worker_metrics = WorkerMetrics::from_config(&config); worker_metrics.set_thread_id(thread::current().id()); @@ -147,7 +147,7 @@ impl CurrentThread { .unwrap_or(DEFAULT_GLOBAL_QUEUE_INTERVAL); let handle = Arc::new(Handle { - runtime_name, + name, task_hooks: TaskHooks { task_spawn_callback: config.before_spawn.clone(), task_terminate_callback: config.after_termination.clone(), @@ -646,8 +646,8 @@ impl Handle { self.shared.owned.id } - pub(crate) fn runtime_name(&self) -> String { - self.runtime_name.clone() + pub(crate) fn name(&self) -> Option<&str> { + self.name.as_deref() } } diff --git a/tokio/src/runtime/scheduler/multi_thread/handle.rs b/tokio/src/runtime/scheduler/multi_thread/handle.rs index 752ac422072..d66f91ed65f 100644 --- a/tokio/src/runtime/scheduler/multi_thread/handle.rs +++ b/tokio/src/runtime/scheduler/multi_thread/handle.rs @@ -23,8 +23,8 @@ use crate::loom::sync::atomic::{AtomicBool, Ordering::SeqCst}; /// Handle to the multi thread scheduler pub(crate) struct Handle { - /// - pub(crate) runtime_name: String, + /// The name of the runtime + pub(crate) name: Option, /// Task spawner pub(super) shared: worker::Shared, @@ -127,8 +127,8 @@ impl Handle { self.shared.owned.id } - pub(crate) fn runtime_name(&self) -> String { - self.runtime_name.clone() + pub(crate) fn name(&self) -> Option<&str> { + self.name.as_deref() } } diff --git a/tokio/src/runtime/scheduler/multi_thread/mod.rs b/tokio/src/runtime/scheduler/multi_thread/mod.rs index 1881705f149..fd417b37e37 100644 --- a/tokio/src/runtime/scheduler/multi_thread/mod.rs +++ b/tokio/src/runtime/scheduler/multi_thread/mod.rs @@ -62,7 +62,7 @@ impl MultiThread { seed_generator: RngSeedGenerator, config: Config, timer_flavor: TimerFlavor, - runtime_name: String, + name: Option, ) -> (MultiThread, Arc, Launch) { let parker = Parker::new(driver); let (handle, launch) = worker::create( @@ -73,7 +73,7 @@ impl MultiThread { seed_generator, config, timer_flavor, - runtime_name, + name, ); (MultiThread, handle, launch) diff --git a/tokio/src/runtime/scheduler/multi_thread/worker.rs b/tokio/src/runtime/scheduler/multi_thread/worker.rs index 582f7b3a1fe..3787b5a8167 100644 --- a/tokio/src/runtime/scheduler/multi_thread/worker.rs +++ b/tokio/src/runtime/scheduler/multi_thread/worker.rs @@ -262,7 +262,7 @@ pub(super) fn create( seed_generator: RngSeedGenerator, config: Config, timer_flavor: TimerFlavor, - runtime_name: String, + name: Option, ) -> (Arc, Launch) { let mut cores = Vec::with_capacity(size); let mut remotes = Vec::with_capacity(size); @@ -302,7 +302,7 @@ pub(super) fn create( let remotes_len = remotes.len(); let handle = Arc::new(Handle { - runtime_name: runtime_name, + name, task_hooks: TaskHooks::from_config(&config), shared: Shared { remotes: remotes.into_boxed_slice(), From 61666b1b2291208dc4aea0460bf6f5e8c327966c Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 16:18:36 +0100 Subject: [PATCH 05/19] improve docs --- tokio/src/runtime/builder.rs | 2 +- tokio/src/runtime/handle.rs | 3 +-- tokio/src/runtime/scheduler/current_thread/mod.rs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tokio/src/runtime/builder.rs b/tokio/src/runtime/builder.rs index 3dbb1da41e7..6f97008a09e 100644 --- a/tokio/src/runtime/builder.rs +++ b/tokio/src/runtime/builder.rs @@ -54,7 +54,7 @@ pub struct Builder { /// Runtime type kind: Kind, - /// Name used for the runtime. + /// Name of the runtime. name: Option, /// Whether or not to enable the I/O driver diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index 5ef565bf646..53f92d80de3 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -483,11 +483,10 @@ impl Handle { /// /// #[tokio::main(flavor = "current_thread")] /// async fn main() { - /// println!("Current runtime id: {}", Handle::current().name().unwrap(); + /// println!("Current runtime name: {}", Handle::current().name().unwrap(); /// } /// ``` /// - /// [`Id`]: struct@crate::runtime::Id pub fn name(&self) -> Option<&str> { match &self.inner { scheduler::Handle::CurrentThread(handle) => handle.name(), diff --git a/tokio/src/runtime/scheduler/current_thread/mod.rs b/tokio/src/runtime/scheduler/current_thread/mod.rs index dd7c6fa3010..bcd0d773359 100644 --- a/tokio/src/runtime/scheduler/current_thread/mod.rs +++ b/tokio/src/runtime/scheduler/current_thread/mod.rs @@ -35,7 +35,7 @@ pub(crate) struct CurrentThread { /// Handle to the current thread scheduler pub(crate) struct Handle { - /// The name of runtime + /// The name of the runtime pub(crate) name: Option, /// Scheduler state shared across threads From 7a347280d7e2cb188cc98a8242b4b8ba76df4e60 Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 16:19:52 +0100 Subject: [PATCH 06/19] improve docs --- tokio/src/runtime/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio/src/runtime/builder.rs b/tokio/src/runtime/builder.rs index 6f97008a09e..e5f53647a2b 100644 --- a/tokio/src/runtime/builder.rs +++ b/tokio/src/runtime/builder.rs @@ -544,7 +544,7 @@ impl Builder { self } - /// Sets name of the runtime. + /// Sets the name of the runtime. /// /// # Examples /// From 7e69fdf53860878bc3db0b4706c97cad1f8b11eb Mon Sep 17 00:00:00 2001 From: Mattia Pitossi Date: Fri, 20 Feb 2026 17:16:36 +0100 Subject: [PATCH 07/19] fix CI warnings --- tokio/src/runtime/handle.rs | 2 +- tokio/src/runtime/scheduler/current_thread/mod.rs | 1 - tokio/src/runtime/scheduler/multi_thread/mod.rs | 1 + tokio/src/runtime/scheduler/multi_thread/worker.rs | 1 + 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index 53f92d80de3..00b01e95ad4 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -483,7 +483,7 @@ impl Handle { /// /// #[tokio::main(flavor = "current_thread")] /// async fn main() { - /// println!("Current runtime name: {}", Handle::current().name().unwrap(); + /// println!("Current runtime name: {}", Handle::current().name().unwrap()); /// } /// ``` /// diff --git a/tokio/src/runtime/scheduler/current_thread/mod.rs b/tokio/src/runtime/scheduler/current_thread/mod.rs index bcd0d773359..41b693e35fa 100644 --- a/tokio/src/runtime/scheduler/current_thread/mod.rs +++ b/tokio/src/runtime/scheduler/current_thread/mod.rs @@ -34,7 +34,6 @@ pub(crate) struct CurrentThread { /// Handle to the current thread scheduler pub(crate) struct Handle { - /// The name of the runtime pub(crate) name: Option, diff --git a/tokio/src/runtime/scheduler/multi_thread/mod.rs b/tokio/src/runtime/scheduler/multi_thread/mod.rs index fd417b37e37..c04a3ef55a6 100644 --- a/tokio/src/runtime/scheduler/multi_thread/mod.rs +++ b/tokio/src/runtime/scheduler/multi_thread/mod.rs @@ -54,6 +54,7 @@ pub(crate) struct MultiThread; // ===== impl MultiThread ===== impl MultiThread { + #[allow(clippy::too_many_arguments)] pub(crate) fn new( size: usize, driver: Driver, diff --git a/tokio/src/runtime/scheduler/multi_thread/worker.rs b/tokio/src/runtime/scheduler/multi_thread/worker.rs index 3787b5a8167..4d530fa2eae 100644 --- a/tokio/src/runtime/scheduler/multi_thread/worker.rs +++ b/tokio/src/runtime/scheduler/multi_thread/worker.rs @@ -254,6 +254,7 @@ type Notified = task::Notified>; /// improvements. const MAX_LIFO_POLLS_PER_TICK: usize = 3; +#[allow(clippy::too_many_arguments)] pub(super) fn create( size: usize, park: Parker, From c34ff6209aeded7db48b5dd2e53985ff69c27d31 Mon Sep 17 00:00:00 2001 From: Mattia Pitossi Date: Fri, 20 Feb 2026 17:57:06 +0100 Subject: [PATCH 08/19] fix unwrap --- tokio/src/runtime/handle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index 00b01e95ad4..1a4e3c3ac83 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -483,7 +483,7 @@ impl Handle { /// /// #[tokio::main(flavor = "current_thread")] /// async fn main() { - /// println!("Current runtime name: {}", Handle::current().name().unwrap()); + /// println!("Current runtime name: {}", Handle::current().name().unwrap_or("unnamed"); /// } /// ``` /// From 994e4cef50dcc6d157129b288104fe9c1bccfe20 Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 18:02:02 +0100 Subject: [PATCH 09/19] add name macro for runtime --- tokio-macros/src/entry.rs | 21 +++++++++++++++++++++ tokio/src/runtime/handle.rs | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/tokio-macros/src/entry.rs b/tokio-macros/src/entry.rs index 5f52f29468f..d01d2f1073a 100644 --- a/tokio-macros/src/entry.rs +++ b/tokio-macros/src/entry.rs @@ -53,6 +53,7 @@ impl UnhandledPanic { } struct FinalConfig { + name: Option, flavor: RuntimeFlavor, worker_threads: Option, start_paused: Option, @@ -62,6 +63,7 @@ struct FinalConfig { /// Config used in case of the attribute not being able to build a valid config const DEFAULT_ERROR_CONFIG: FinalConfig = FinalConfig { + name: None, flavor: RuntimeFlavor::CurrentThread, worker_threads: None, start_paused: None, @@ -70,6 +72,7 @@ const DEFAULT_ERROR_CONFIG: FinalConfig = FinalConfig { }; struct Configuration { + name: Option, rt_multi_thread_available: bool, default_flavor: RuntimeFlavor, flavor: Option, @@ -83,6 +86,7 @@ struct Configuration { impl Configuration { fn new(is_test: bool, rt_multi_thread: bool) -> Self { Configuration { + name: None, rt_multi_thread_available: rt_multi_thread, default_flavor: match is_test { true => RuntimeFlavor::CurrentThread, @@ -97,6 +101,16 @@ impl Configuration { } } + fn set_name(&mut self, name: syn::Lit, span: Span) -> Result<(), syn::Error> { + if self.name.is_some() { + return Err(syn::Error::new(span, "`name` set multiple times.")); + } + + let runtime_name = parse_string(name, span, "name")?; + self.name = Some(runtime_name); + Ok(()) + } + fn set_flavor(&mut self, runtime: syn::Lit, span: Span) -> Result<(), syn::Error> { if self.flavor.is_some() { return Err(syn::Error::new(span, "`flavor` set multiple times.")); @@ -227,6 +241,7 @@ impl Configuration { }; Ok(FinalConfig { + name: self.name.clone(), crate_name: self.crate_name.clone(), flavor, worker_threads, @@ -372,6 +387,9 @@ fn build_config( config .set_unhandled_panic(lit.clone(), syn::spanned::Spanned::span(lit))?; } + "name" => { + config.set_name(lit.clone(), syn::spanned::Spanned::span(lit))?; + } name => { let msg = format!( "Unknown attribute {name} is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`", @@ -478,6 +496,9 @@ fn parse_knobs(mut input: ItemFn, is_test: bool, config: FinalConfig) -> TokenSt let unhandled_panic = v.into_tokens(&crate_path); rt = quote_spanned! {last_stmt_start_span=> #rt.unhandled_panic(#unhandled_panic) }; } + if let Some(v) = config.name { + rt = quote_spanned! {last_stmt_start_span=> #rt.name(#v) }; + } let generated_attrs = if is_test { quote! { diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index 1a4e3c3ac83..22f67629def 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -481,7 +481,7 @@ impl Handle { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main(flavor = "current_thread")] + /// #[tokio::main(flavor = "current_thread", name = "my-runtime")] /// async fn main() { /// println!("Current runtime name: {}", Handle::current().name().unwrap_or("unnamed"); /// } From b24e2c0faec3ee2b606f16129ab9e5d7078122b6 Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 18:03:54 +0100 Subject: [PATCH 10/19] fix unwrap docs --- tokio/src/runtime/handle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index 22f67629def..cb27e4db4f0 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -483,7 +483,7 @@ impl Handle { /// /// #[tokio::main(flavor = "current_thread", name = "my-runtime")] /// async fn main() { - /// println!("Current runtime name: {}", Handle::current().name().unwrap_or("unnamed"); + /// println!("Current runtime name: {}", Handle::current().name().unwrap(); /// } /// ``` /// From dd11e7f9d5a96f9e3a87f591daf2df15a4697f27 Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 18:11:28 +0100 Subject: [PATCH 11/19] add docs for macro runtime name --- .../tests/fail/macros_invalid_input.rs | 3 +++ .../tests/fail/macros_invalid_input.stderr | 6 ++--- tokio-macros/src/lib.rs | 24 +++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/tests-build/tests/fail/macros_invalid_input.rs b/tests-build/tests/fail/macros_invalid_input.rs index 425b274ff7f..126a2e1de0d 100644 --- a/tests-build/tests/fail/macros_invalid_input.rs +++ b/tests-build/tests/fail/macros_invalid_input.rs @@ -41,6 +41,9 @@ async fn test_crate_not_path_int() {} #[tokio::test(crate = "456")] async fn test_crate_not_path_invalid() {} +#[tokio::test(name = 123)] +async fn test_name_not_string() {} + #[tokio::test(flavor = "multi_thread", unhandled_panic = "shutdown_runtime")] async fn test_multi_thread_with_unhandled_panic() {} diff --git a/tests-build/tests/fail/macros_invalid_input.stderr b/tests-build/tests/fail/macros_invalid_input.stderr index cfb2f84448a..89e0027c2f2 100644 --- a/tests-build/tests/fail/macros_invalid_input.stderr +++ b/tests-build/tests/fail/macros_invalid_input.stderr @@ -4,7 +4,7 @@ error: the `async` keyword is missing from the function declaration 6 | fn main_is_not_async() {} | ^^ -error: Unknown attribute foo is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`. +error: Unknown attribute foo is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`, `name`. --> tests/fail/macros_invalid_input.rs:8:15 | 8 | #[tokio::main(foo)] @@ -22,13 +22,13 @@ error: the `async` keyword is missing from the function declaration 15 | fn test_is_not_async() {} | ^^ -error: Unknown attribute foo is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`. +error: Unknown attribute foo is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`, `name`. --> tests/fail/macros_invalid_input.rs:17:15 | 17 | #[tokio::test(foo)] | ^^^ -error: Unknown attribute foo is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic` +error: Unknown attribute foo is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`, `name`. --> tests/fail/macros_invalid_input.rs:20:15 | 20 | #[tokio::test(foo = 123)] diff --git a/tokio-macros/src/lib.rs b/tokio-macros/src/lib.rs index cd4cba0a24b..2dde2952874 100644 --- a/tokio-macros/src/lib.rs +++ b/tokio-macros/src/lib.rs @@ -91,6 +91,30 @@ use proc_macro::TokenStream; /// /// # Usage /// +/// ## Set the name of the runtime +/// +/// ```rust +/// #[tokio::main(name = "my-runtime")] +/// async fn main() { +/// println!("Hello world"); +/// } +/// ``` +/// +/// Equivalent code not using `#[tokio::main]` +/// +/// ```rust +/// fn main() { +/// tokio::runtime::Builder::new_multi_thread() +/// .enable_all() +/// .name("my-runtime") +/// .build() +/// .unwrap() +/// .block_on(async { +/// println!("Hello world"); +/// }) +/// } +/// ``` +/// /// ## Using the multi-threaded runtime /// /// ```rust From b4db30c7c6da8126d8c877fedefdb33ab9e6573a Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 18:16:35 +0100 Subject: [PATCH 12/19] add docs for test macro --- tokio-macros/src/lib.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tokio-macros/src/lib.rs b/tokio-macros/src/lib.rs index 2dde2952874..9f999df6f9e 100644 --- a/tokio-macros/src/lib.rs +++ b/tokio-macros/src/lib.rs @@ -432,6 +432,31 @@ pub fn main_rt(args: TokenStream, item: TokenStream) -> TokenStream { /// /// ## Usage /// +/// ### Set the name of the runtime +/// +/// ```no_run +/// #[tokio::test(name = "my-test-runtime")] +/// async fn my_test() { +/// assert!(true); +/// } +/// ``` +/// +/// Equivalent code not using `#[tokio::test]` +/// +/// ```no_run +/// #[test] +/// fn my_test() { +/// tokio::runtime::Builder::new_current_thread() +/// .enable_all() +/// .name("my-test-runtime") +/// .build() +/// .unwrap() +/// .block_on(async { +/// assert!(true); +/// }) +/// } +/// ``` +/// /// ### Using the multi-thread runtime /// /// ```no_run From 33d95c173c31cf82053faacd7ac37e8613a32be6 Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 18:23:24 +0100 Subject: [PATCH 13/19] fix docs --- tokio-macros/src/entry.rs | 6 +++--- tokio/src/runtime/handle.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tokio-macros/src/entry.rs b/tokio-macros/src/entry.rs index d01d2f1073a..d425b207291 100644 --- a/tokio-macros/src/entry.rs +++ b/tokio-macros/src/entry.rs @@ -392,7 +392,7 @@ fn build_config( } name => { let msg = format!( - "Unknown attribute {name} is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`", + "Unknown attribute {name} is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`, `name`.", ); return Err(syn::Error::new_spanned(namevalue, msg)); } @@ -415,11 +415,11 @@ fn build_config( "Set the runtime flavor with #[{macro_name}(flavor = \"current_thread\")]." ) } - "flavor" | "worker_threads" | "start_paused" | "crate" | "unhandled_panic" => { + "flavor" | "worker_threads" | "start_paused" | "crate" | "unhandled_panic" | "name" => { format!("The `{name}` attribute requires an argument.") } name => { - format!("Unknown attribute {name} is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`.") + format!("Unknown attribute {name} is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`, `unhandled_panic`, `name`.") } }; return Err(syn::Error::new_spanned(path, msg)); diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index cb27e4db4f0..31e1a52980d 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -483,7 +483,7 @@ impl Handle { /// /// #[tokio::main(flavor = "current_thread", name = "my-runtime")] /// async fn main() { - /// println!("Current runtime name: {}", Handle::current().name().unwrap(); + /// println!("Current runtime name: {}", Handle::current().name().unwrap()); /// } /// ``` /// From 5c207a04a2235dd25dbb8f1c073eaf896a93fc7e Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 18:25:21 +0100 Subject: [PATCH 14/19] rustfmt --- tokio-macros/src/entry.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tokio-macros/src/entry.rs b/tokio-macros/src/entry.rs index d425b207291..476006703d1 100644 --- a/tokio-macros/src/entry.rs +++ b/tokio-macros/src/entry.rs @@ -415,7 +415,8 @@ fn build_config( "Set the runtime flavor with #[{macro_name}(flavor = \"current_thread\")]." ) } - "flavor" | "worker_threads" | "start_paused" | "crate" | "unhandled_panic" | "name" => { + "flavor" | "worker_threads" | "start_paused" | "crate" | "unhandled_panic" + | "name" => { format!("The `{name}` attribute requires an argument.") } name => { From f3575310bc477625a52af71aa2773c46a15015c3 Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 18:46:00 +0100 Subject: [PATCH 15/19] fix diagnostic file --- tests-build/tests/fail/macros_invalid_input.rs | 6 +++--- tests-build/tests/fail/macros_invalid_input.stderr | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests-build/tests/fail/macros_invalid_input.rs b/tests-build/tests/fail/macros_invalid_input.rs index 126a2e1de0d..5e89a651049 100644 --- a/tests-build/tests/fail/macros_invalid_input.rs +++ b/tests-build/tests/fail/macros_invalid_input.rs @@ -41,9 +41,6 @@ async fn test_crate_not_path_int() {} #[tokio::test(crate = "456")] async fn test_crate_not_path_invalid() {} -#[tokio::test(name = 123)] -async fn test_name_not_string() {} - #[tokio::test(flavor = "multi_thread", unhandled_panic = "shutdown_runtime")] async fn test_multi_thread_with_unhandled_panic() {} @@ -71,4 +68,7 @@ async fn test_has_second_test_attr_rust_2021() {} #[tokio::test] async fn test_has_generated_second_test_attr() {} +#[tokio::test(name = 123)] +async fn test_name_not_string() {} + fn main() {} diff --git a/tests-build/tests/fail/macros_invalid_input.stderr b/tests-build/tests/fail/macros_invalid_input.stderr index 89e0027c2f2..8bc26668135 100644 --- a/tests-build/tests/fail/macros_invalid_input.stderr +++ b/tests-build/tests/fail/macros_invalid_input.stderr @@ -119,3 +119,9 @@ error: second test attribute is supplied, consider removing or changing the orde | ^^^^^^^^^^^^^^ | = note: this error originates in the attribute macro `tokio::test` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: Failed to parse value of `name` as string. + --> tests/fail/macros_invalid_input.rs:71:22 + | +71 | #[tokio::test(name = 123)] + | ^^^ From 5c3d7a5c05348ad2193bf50bf18560da70745198 Mon Sep 17 00:00:00 2001 From: mattiapitossi Date: Fri, 20 Feb 2026 18:55:39 +0100 Subject: [PATCH 16/19] use path due to unreleased changes --- tokio-macros/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio-macros/Cargo.toml b/tokio-macros/Cargo.toml index f3b2dbbff45..b7cb500a724 100644 --- a/tokio-macros/Cargo.toml +++ b/tokio-macros/Cargo.toml @@ -27,7 +27,7 @@ quote = "1" syn = { version = "2.0", features = ["full"] } [dev-dependencies] -tokio = { version = "1.0.0", features = ["full", "test-util"] } +tokio = { path = "../tokio", features = ["full", "test-util"] } [package.metadata.docs.rs] all-features = true From b7d913f7400fcb1863e64be6740a934f3dc3915e Mon Sep 17 00:00:00 2001 From: Mattia Pitossi Date: Fri, 20 Feb 2026 20:14:23 +0100 Subject: [PATCH 17/19] set tokio version --- tokio-macros/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio-macros/Cargo.toml b/tokio-macros/Cargo.toml index b7cb500a724..4a44ceab9ac 100644 --- a/tokio-macros/Cargo.toml +++ b/tokio-macros/Cargo.toml @@ -27,7 +27,7 @@ quote = "1" syn = { version = "2.0", features = ["full"] } [dev-dependencies] -tokio = { path = "../tokio", features = ["full", "test-util"] } +tokio = { version = "1.0.0", path = "../tokio", features = ["full", "test-util"] } [package.metadata.docs.rs] all-features = true From a570a7ab5c23c9c9c65d99bb34c9a0ec734dcd9f Mon Sep 17 00:00:00 2001 From: Mattia Pitossi Date: Sat, 21 Feb 2026 09:46:32 +0100 Subject: [PATCH 18/19] add test for the name builder --- tokio/tests/rt_threaded.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tokio/tests/rt_threaded.rs b/tokio/tests/rt_threaded.rs index 432add50f38..f1730e881a6 100644 --- a/tokio/tests/rt_threaded.rs +++ b/tokio/tests/rt_threaded.rs @@ -860,6 +860,20 @@ fn test_tuning() { flag.store(false, Relaxed); } +#[test] +fn different_runtime_names() { + let rt1 = runtime::Builder::new_multi_thread() + .name("test-runtime-1") + .build() + .unwrap(); + let rt2 = runtime::Builder::new_multi_thread() + .name("test-runtime-2") + .build() + .unwrap(); + + assert_ne!(rt1.handle().name().unwrap(), rt2.handle().name().unwrap()); +} + fn rt() -> runtime::Runtime { runtime::Runtime::new().unwrap() } From 92a3f7f948385bed1f633adbc2caee0fe98549eb Mon Sep 17 00:00:00 2001 From: Mattia Pitossi Date: Sat, 21 Feb 2026 09:53:36 +0100 Subject: [PATCH 19/19] trigger ci