tokio/runtime/scheduler/multi_thread/
mod.rs

1//! Multi-threaded runtime
2
3mod counters;
4use counters::Counters;
5
6mod handle;
7pub(crate) use handle::Handle;
8
9mod overflow;
10pub(crate) use overflow::Overflow;
11
12mod idle;
13use self::idle::Idle;
14
15mod stats;
16pub(crate) use stats::Stats;
17
18mod park;
19pub(crate) use park::{Parker, Unparker};
20
21pub(crate) mod queue;
22
23mod worker;
24pub(crate) use worker::{Context, Launch, Shared};
25
26cfg_taskdump! {
27    mod trace;
28    use trace::TraceStatus;
29
30    pub(crate) use worker::Synced;
31}
32
33cfg_not_taskdump! {
34    mod trace_mock;
35    use trace_mock::TraceStatus;
36}
37
38pub(crate) use worker::block_in_place;
39
40use crate::loom::sync::Arc;
41use crate::runtime::{
42    blocking,
43    driver::{self, Driver},
44    scheduler, Config, TimerFlavor,
45};
46use crate::util::RngSeedGenerator;
47
48use std::fmt;
49use std::future::Future;
50
51/// Work-stealing based thread pool for executing futures.
52pub(crate) struct MultiThread;
53
54// ===== impl MultiThread =====
55
56impl MultiThread {
57    #[allow(clippy::too_many_arguments)]
58    pub(crate) fn new(
59        size: usize,
60        driver: Driver,
61        driver_handle: driver::Handle,
62        blocking_spawner: blocking::Spawner,
63        seed_generator: RngSeedGenerator,
64        config: Config,
65        timer_flavor: TimerFlavor,
66        name: Option<String>,
67    ) -> (MultiThread, Arc<Handle>, Launch) {
68        let parker = Parker::new(driver);
69        let (handle, launch) = worker::create(
70            size,
71            parker,
72            driver_handle,
73            blocking_spawner,
74            seed_generator,
75            config,
76            timer_flavor,
77            name,
78        );
79
80        (MultiThread, handle, launch)
81    }
82
83    /// Blocks the current thread waiting for the future to complete.
84    ///
85    /// The future will execute on the current thread, but all spawned tasks
86    /// will be executed on the thread pool.
87    pub(crate) fn block_on<F>(&self, handle: &scheduler::Handle, future: F) -> F::Output
88    where
89        F: Future,
90    {
91        crate::runtime::context::enter_runtime(handle, true, |blocking| {
92            blocking.block_on(future).expect("failed to park thread")
93        })
94    }
95
96    pub(crate) fn shutdown(&mut self, handle: &scheduler::Handle) {
97        match handle {
98            scheduler::Handle::MultiThread(handle) => handle.shutdown(),
99            _ => panic!("expected MultiThread scheduler"),
100        }
101    }
102}
103
104impl fmt::Debug for MultiThread {
105    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
106        fmt.debug_struct("MultiThread").finish()
107    }
108}