Start removing the Send impl for App
Co-authored-by: Antonio <antonio@zed.dev> Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
parent
ea7fdef417
commit
57ffa8201e
38 changed files with 506 additions and 932 deletions
|
@ -6,6 +6,7 @@ use std::{
|
|||
marker::PhantomData,
|
||||
mem,
|
||||
pin::Pin,
|
||||
rc::Rc,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering::SeqCst},
|
||||
Arc,
|
||||
|
@ -17,10 +18,16 @@ use util::TryFutureExt;
|
|||
use waker_fn::waker_fn;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Executor {
|
||||
pub struct BackgroundExecutor {
|
||||
dispatcher: Arc<dyn PlatformDispatcher>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ForegroundExecutor {
|
||||
dispatcher: Arc<dyn PlatformDispatcher>,
|
||||
not_send: PhantomData<Rc<()>>,
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub enum Task<T> {
|
||||
Ready(Option<T>),
|
||||
|
@ -61,7 +68,7 @@ impl<T> Future for Task<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Executor {
|
||||
impl BackgroundExecutor {
|
||||
pub fn new(dispatcher: Arc<dyn PlatformDispatcher>) -> Self {
|
||||
Self { dispatcher }
|
||||
}
|
||||
|
@ -79,63 +86,6 @@ impl Executor {
|
|||
Task::Spawned(task)
|
||||
}
|
||||
|
||||
/// Enqueues the given closure to run on the application's event loop.
|
||||
/// Returns the result asynchronously.
|
||||
pub fn run_on_main<F, R>(&self, func: F) -> Task<R>
|
||||
where
|
||||
F: FnOnce() -> R + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
if self.dispatcher.is_main_thread() {
|
||||
Task::ready(func())
|
||||
} else {
|
||||
self.spawn_on_main(move || async move { func() })
|
||||
}
|
||||
}
|
||||
|
||||
/// Enqueues the given closure to be run on the application's event loop. The
|
||||
/// closure returns a future which will be run to completion on the main thread.
|
||||
pub fn spawn_on_main<F, R>(&self, func: impl FnOnce() -> F + Send + 'static) -> Task<R>
|
||||
where
|
||||
F: Future<Output = R> + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
let (runnable, task) = async_task::spawn(
|
||||
{
|
||||
let this = self.clone();
|
||||
async move {
|
||||
let task = this.spawn_on_main_local(func());
|
||||
task.await
|
||||
}
|
||||
},
|
||||
{
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
move |runnable| dispatcher.dispatch_on_main_thread(runnable)
|
||||
},
|
||||
);
|
||||
runnable.schedule();
|
||||
Task::Spawned(task)
|
||||
}
|
||||
|
||||
/// Enqueues the given closure to be run on the application's event loop. Must
|
||||
/// be called on the main thread.
|
||||
pub fn spawn_on_main_local<R>(&self, future: impl Future<Output = R> + 'static) -> Task<R>
|
||||
where
|
||||
R: 'static,
|
||||
{
|
||||
assert!(
|
||||
self.dispatcher.is_main_thread(),
|
||||
"must be called on main thread"
|
||||
);
|
||||
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
let (runnable, task) = async_task::spawn_local(future, move |runnable| {
|
||||
dispatcher.dispatch_on_main_thread(runnable)
|
||||
});
|
||||
runnable.schedule();
|
||||
Task::Spawned(task)
|
||||
}
|
||||
|
||||
pub fn block<R>(&self, future: impl Future<Output = R>) -> R {
|
||||
pin_mut!(future);
|
||||
let (parker, unparker) = parking::pair();
|
||||
|
@ -261,8 +211,31 @@ impl Executor {
|
|||
}
|
||||
}
|
||||
|
||||
impl ForegroundExecutor {
|
||||
pub fn new(dispatcher: Arc<dyn PlatformDispatcher>) -> Self {
|
||||
Self {
|
||||
dispatcher,
|
||||
not_send: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Enqueues the given closure to be run on any thread. The closure returns
|
||||
/// a future which will be run to completion on any available thread.
|
||||
pub fn spawn<R>(&self, future: impl Future<Output = R> + 'static) -> Task<R>
|
||||
where
|
||||
R: 'static,
|
||||
{
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
let (runnable, task) = async_task::spawn_local(future, move |runnable| {
|
||||
dispatcher.dispatch_on_main_thread(runnable)
|
||||
});
|
||||
runnable.schedule();
|
||||
Task::Spawned(task)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Scope<'a> {
|
||||
executor: Executor,
|
||||
executor: BackgroundExecutor,
|
||||
futures: Vec<Pin<Box<dyn Future<Output = ()> + Send + 'static>>>,
|
||||
tx: Option<mpsc::Sender<()>>,
|
||||
rx: mpsc::Receiver<()>,
|
||||
|
@ -270,7 +243,7 @@ pub struct Scope<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Scope<'a> {
|
||||
fn new(executor: Executor) -> Self {
|
||||
fn new(executor: BackgroundExecutor) -> Self {
|
||||
let (tx, rx) = mpsc::channel(1);
|
||||
Self {
|
||||
executor,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue