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
}