aboutsummaryrefslogtreecommitdiff
path: root/core/src/async_util/executor.rs
blob: 3e7aa06af8fa68d03ce16a294286152dc191c557 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use std::{panic::catch_unwind, sync::Arc, thread};

use async_lock::OnceCell;
use smol::Executor as SmolEx;

static GLOBAL_EXECUTOR: OnceCell<Arc<smol::Executor<'_>>> = OnceCell::new();

/// A pointer to an Executor
pub type Executor<'a> = Arc<SmolEx<'a>>;

/// Returns a single-threaded global executor
pub(crate) fn global_executor() -> Executor<'static> {
    fn init_executor() -> Executor<'static> {
        let ex = smol::Executor::new();
        thread::Builder::new()
            .spawn(|| loop {
                catch_unwind(|| {
                    smol::block_on(global_executor().run(smol::future::pending::<()>()))
                })
                .ok();
            })
            .expect("cannot spawn executor thread");
        // Prevent spawning another thread by running the process driver on this
        // thread. see https://github.com/smol-rs/smol/blob/master/src/spawn.rs
        ex.spawn(async_process::driver()).detach();
        Arc::new(ex)
    }

    GLOBAL_EXECUTOR.get_or_init_blocking(init_executor).clone()
}