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