async_global_executor/
executor.rs

1use crate::Task;
2use async_executor::{Executor, LocalExecutor};
3use std::future::Future;
4
5pub(crate) static GLOBAL_EXECUTOR: Executor<'_> = Executor::new();
6
7thread_local! {
8    pub(crate) static LOCAL_EXECUTOR: LocalExecutor<'static> = LocalExecutor::new();
9}
10
11/// Runs the global and the local executor on the current thread
12///
13/// Note: this calls `async_io::block_on` underneath.
14///
15/// # Examples
16///
17/// ```
18/// let task = async_global_executor::spawn(async {
19///     1 + 2
20/// });
21/// async_global_executor::block_on(async {
22///     assert_eq!(task.await, 3);
23/// });
24/// ```
25pub fn block_on<F: Future<Output = T>, T>(future: F) -> T {
26    LOCAL_EXECUTOR.with(|executor| crate::reactor::block_on(executor.run(future)))
27}
28
29/// Spawns a task onto the multi-threaded global executor.
30///
31/// # Examples
32///
33/// ```
34/// # use futures_lite::future;
35///
36/// let task1 = async_global_executor::spawn(async {
37///     1 + 2
38/// });
39/// let task2 = async_global_executor::spawn(async {
40///     3 + 4
41/// });
42/// let task = future::zip(task1, task2);
43///
44/// async_global_executor::block_on(async {
45///     assert_eq!(task.await, (3, 7));
46/// });
47/// ```
48pub fn spawn<F: Future<Output = T> + Send + 'static, T: Send + 'static>(future: F) -> Task<T> {
49    crate::init();
50    GLOBAL_EXECUTOR.spawn(future)
51}
52
53/// Spawns a task onto the local executor.
54///
55///
56/// The task does not need to be `Send` as it will be spawned on the same thread.
57///
58/// # Examples
59///
60/// ```
61/// # use futures_lite::future;
62///
63/// let task1 = async_global_executor::spawn_local(async {
64///     1 + 2
65/// });
66/// let task2 = async_global_executor::spawn_local(async {
67///     3 + 4
68/// });
69/// let task = future::zip(task1, task2);
70///
71/// async_global_executor::block_on(async {
72///     assert_eq!(task.await, (3, 7));
73/// });
74/// ```
75pub fn spawn_local<F: Future<Output = T> + 'static, T: 'static>(future: F) -> Task<T> {
76    LOCAL_EXECUTOR.with(|executor| executor.spawn(future))
77}
78
79/// Runs blocking code on a thread pool.
80///
81/// # Examples
82///
83/// Read the contents of a file:
84///
85/// ```no_run
86/// # async_global_executor::block_on(async {
87/// let contents = async_global_executor::spawn_blocking(|| std::fs::read_to_string("file.txt")).await?;
88/// # std::io::Result::Ok(()) });
89/// ```
90///
91/// Spawn a process:
92///
93/// ```no_run
94/// use std::process::Command;
95///
96/// # async_global_executor::block_on(async {
97/// let out = async_global_executor::spawn_blocking(|| Command::new("dir").output()).await?;
98/// # std::io::Result::Ok(()) });
99/// ```
100pub fn spawn_blocking<F: FnOnce() -> T + Send + 'static, T: Send + 'static>(f: F) -> Task<T> {
101    blocking::unblock(f)
102}