1 use crate::Task;
2 use async_executor::{Executor, LocalExecutor};
3 use std::future::Future;
4 
5 pub(crate) static GLOBAL_EXECUTOR: Executor<'_> = Executor::new();
6 
7 thread_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 /// ```
block_on<F: Future<Output = T>, T>(future: F) -> T25 pub 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 /// ```
spawn<F: Future<Output = T> + Send + 'static, T: Send + 'static>(future: F) -> Task<T>48 pub 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 /// ```
spawn_local<F: Future<Output = T> + 'static, T: 'static>(future: F) -> Task<T>75 pub 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 /// ```
spawn_blocking<F: FnOnce() -> T + Send + 'static, T: Send + 'static>(f: F) -> T100 pub async fn spawn_blocking<F: FnOnce() -> T + Send + 'static, T: Send + 'static>(f: F) -> T {
101     blocking::unblock(f).await
102 }
103