-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
make a safer abstraction for the main thread executor
- Loading branch information
Showing
5 changed files
with
96 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
use std::{marker::PhantomData, sync::Arc}; | ||
|
||
use async_executor::{Executor, Task}; | ||
use futures_lite::Future; | ||
use is_main_thread::is_main_thread; | ||
use once_cell::sync::OnceCell; | ||
|
||
static MAIN_THREAD_EXECUTOR: OnceCell<MainThreadExecutor> = OnceCell::new(); | ||
|
||
/// Use to access the global main thread executor. Be aware that the main thread executor | ||
/// only makes progress when it is ticked. This normally happens in `[TaskPool::scope]`. | ||
#[derive(Debug)] | ||
pub struct MainThreadExecutor(Arc<Executor<'static>>); | ||
|
||
impl MainThreadExecutor { | ||
/// Initializes the global `[MainThreadExecutor]` instance. | ||
pub fn init() -> &'static Self { | ||
MAIN_THREAD_EXECUTOR.get_or_init(|| Self(Arc::new(Executor::new()))) | ||
} | ||
|
||
/// Gets the global [`MainThreadExecutor`] instance. | ||
/// | ||
/// # Panics | ||
/// Panics if no executor has been initialized yet. | ||
pub fn get() -> &'static Self { | ||
MAIN_THREAD_EXECUTOR.get().expect( | ||
"A MainThreadExecutor has not been initialize yet. Please call \ | ||
MainThreadExecutor::init beforehand", | ||
) | ||
} | ||
|
||
/// Gets the `[MainThreadSpawner]` for the global main thread executor. | ||
/// Use this to spawn tasks on the main thread. | ||
pub fn spawner(&self) -> MainThreadSpawner<'static> { | ||
MainThreadSpawner(self.0.clone()) | ||
} | ||
|
||
/// Gets the `[MainThreadTicker]` for the global main thread executor. | ||
/// Use this to tick the main thread executor. | ||
/// Returns None if called on not the main thread. | ||
pub fn ticker(&self) -> Option<MainThreadTicker> { | ||
if let Some(is_main) = is_main_thread() { | ||
if is_main { | ||
return Some(MainThreadTicker { | ||
executor: self.0.clone(), | ||
_marker: PhantomData::default(), | ||
}); | ||
} | ||
} | ||
None | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct MainThreadSpawner<'a>(Arc<Executor<'a>>); | ||
impl<'a> MainThreadSpawner<'a> { | ||
/// Spawn a task on the main thread | ||
pub fn spawn<T: Send + 'a>(&self, future: impl Future<Output = T> + Send + 'a) -> Task<T> { | ||
self.0.spawn(future) | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct MainThreadTicker { | ||
executor: Arc<Executor<'static>>, | ||
// make type not send or sync | ||
_marker: PhantomData<*const ()>, | ||
} | ||
impl MainThreadTicker { | ||
/// Tick the main thread executor. | ||
/// This needs to be called manually on the main thread if a `[TaskPool::scope]` is not active | ||
pub fn tick<'a>(&'a self) -> impl Future<Output = ()> + 'a { | ||
self.executor.tick() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters