Rollup merge of #53068 - MajorBreakfast:spawn, r=cramertj
Rename Executor trait to Spawn Renames the `Executor` trait to `Spawn` and the method on `Context` to `spawner`. Note: Best only merge this after we've the alpha 3 announcement post ready. r? @cramertj
This commit is contained in:
commit
3385cae74a
@ -67,7 +67,7 @@ use core::marker::{Unpin, Unsize};
|
||||
use core::mem::{self, PinMut};
|
||||
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
|
||||
use core::ptr::{self, NonNull, Unique};
|
||||
use core::task::{Context, Poll, Executor, SpawnErrorKind, SpawnObjError};
|
||||
use core::task::{Context, Poll, Spawn, SpawnErrorKind, SpawnObjError};
|
||||
|
||||
use raw_vec::RawVec;
|
||||
use str::from_boxed_utf8_unchecked;
|
||||
@ -973,11 +973,14 @@ unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinBox<F>
|
||||
}
|
||||
|
||||
#[unstable(feature = "futures_api", issue = "50547")]
|
||||
impl<E> Executor for Box<E>
|
||||
where E: Executor + ?Sized
|
||||
impl<Sp> Spawn for Box<Sp>
|
||||
where Sp: Spawn + ?Sized
|
||||
{
|
||||
fn spawn_obj(&mut self, task: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
|
||||
(**self).spawn_obj(task)
|
||||
fn spawn_obj(
|
||||
&mut self,
|
||||
future: FutureObj<'static, ()>,
|
||||
) -> Result<(), SpawnObjError> {
|
||||
(**self).spawn_obj(future)
|
||||
}
|
||||
|
||||
fn status(&self) -> Result<(), SpawnErrorKind> {
|
||||
|
@ -13,7 +13,7 @@
|
||||
issue = "50547")]
|
||||
|
||||
use fmt;
|
||||
use super::{Executor, Waker, LocalWaker};
|
||||
use super::{Spawn, Waker, LocalWaker};
|
||||
|
||||
/// Information about the currently-running task.
|
||||
///
|
||||
@ -21,7 +21,7 @@ use super::{Executor, Waker, LocalWaker};
|
||||
/// when performing a single `poll` step on a task.
|
||||
pub struct Context<'a> {
|
||||
local_waker: &'a LocalWaker,
|
||||
executor: &'a mut dyn Executor,
|
||||
spawner: &'a mut dyn Spawn,
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for Context<'a> {
|
||||
@ -32,13 +32,14 @@ impl<'a> fmt::Debug for Context<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
/// Create a new task `Context` with the provided `local_waker`, `waker`, and `executor`.
|
||||
/// Create a new task `Context` with the provided `local_waker`, `waker`,
|
||||
/// and `spawner`.
|
||||
#[inline]
|
||||
pub fn new(local_waker: &'a LocalWaker, executor: &'a mut dyn Executor) -> Context<'a> {
|
||||
Context {
|
||||
local_waker,
|
||||
executor,
|
||||
}
|
||||
pub fn new(
|
||||
local_waker: &'a LocalWaker,
|
||||
spawner: &'a mut dyn Spawn,
|
||||
) -> Context<'a> {
|
||||
Context { local_waker, spawner }
|
||||
}
|
||||
|
||||
/// Get the `LocalWaker` associated with the current task.
|
||||
@ -53,40 +54,45 @@ impl<'a> Context<'a> {
|
||||
unsafe { &*(self.local_waker as *const LocalWaker as *const Waker) }
|
||||
}
|
||||
|
||||
/// Get the default executor associated with this task.
|
||||
/// Get the spawner associated with this task.
|
||||
///
|
||||
/// This method is useful primarily if you want to explicitly handle
|
||||
/// spawn failures.
|
||||
#[inline]
|
||||
pub fn executor(&mut self) -> &mut dyn Executor {
|
||||
self.executor
|
||||
pub fn spawner(&mut self) -> &mut dyn Spawn {
|
||||
self.spawner
|
||||
}
|
||||
|
||||
/// Produce a context like the current one, but using the given waker instead.
|
||||
/// Produce a context like the current one, but using the given waker
|
||||
/// instead.
|
||||
///
|
||||
/// This advanced method is primarily used when building "internal
|
||||
/// schedulers" within a task, where you want to provide some customized
|
||||
/// wakeup logic.
|
||||
#[inline]
|
||||
pub fn with_waker<'b>(&'b mut self, local_waker: &'b LocalWaker) -> Context<'b> {
|
||||
pub fn with_waker<'b>(
|
||||
&'b mut self,
|
||||
local_waker: &'b LocalWaker,
|
||||
) -> Context<'b> {
|
||||
Context {
|
||||
local_waker,
|
||||
executor: self.executor,
|
||||
spawner: self.spawner,
|
||||
}
|
||||
}
|
||||
|
||||
/// Produce a context like the current one, but using the given executor
|
||||
/// Produce a context like the current one, but using the given spawner
|
||||
/// instead.
|
||||
///
|
||||
/// This advanced method is primarily used when building "internal
|
||||
/// schedulers" within a task.
|
||||
#[inline]
|
||||
pub fn with_executor<'b, E>(&'b mut self, executor: &'b mut E) -> Context<'b>
|
||||
where E: Executor
|
||||
{
|
||||
pub fn with_spawner<'b, Sp: Spawn>(
|
||||
&'b mut self,
|
||||
spawner: &'b mut Sp,
|
||||
) -> Context<'b> {
|
||||
Context {
|
||||
local_waker: self.local_waker,
|
||||
executor,
|
||||
spawner,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,10 +17,8 @@
|
||||
mod context;
|
||||
pub use self::context::Context;
|
||||
|
||||
mod executor;
|
||||
pub use self::executor::{
|
||||
Executor, SpawnErrorKind, SpawnObjError, SpawnLocalObjError
|
||||
};
|
||||
mod spawn;
|
||||
pub use self::spawn::{Spawn, SpawnErrorKind, SpawnObjError, SpawnLocalObjError};
|
||||
|
||||
mod poll;
|
||||
pub use self::poll::Poll;
|
||||
|
@ -15,16 +15,13 @@
|
||||
use fmt;
|
||||
use future::{FutureObj, LocalFutureObj};
|
||||
|
||||
/// A task executor.
|
||||
/// Spawns tasks that poll futures to completion onto its associated task
|
||||
/// executor.
|
||||
///
|
||||
/// Futures are polled until completion by tasks, a kind of lightweight
|
||||
/// "thread". A *task executor* is responsible for the creation of these tasks
|
||||
/// and the coordination of their execution on real operating system threads. In
|
||||
/// particular, whenever a task signals that it can make further progress via a
|
||||
/// wake-up notification, it is the responsibility of the task executor to put
|
||||
/// the task into a queue to continue executing it, i.e. polling the future in
|
||||
/// it, later.
|
||||
pub trait Executor {
|
||||
/// The term "task" refers to a kind of lightweight "thread". Task executors
|
||||
/// are responsible for scheduling the execution of tasks on operating system
|
||||
/// threads.
|
||||
pub trait Spawn {
|
||||
/// Spawns a new task with the given future. The future will be polled until
|
||||
/// completion.
|
||||
///
|
@ -22,7 +22,7 @@ use std::sync::{
|
||||
use std::future::FutureObj;
|
||||
use std::task::{
|
||||
Context, Poll, Wake,
|
||||
Executor, SpawnObjError,
|
||||
Spawn, SpawnObjError,
|
||||
local_waker_from_nonlocal,
|
||||
};
|
||||
|
||||
@ -36,8 +36,8 @@ impl Wake for Counter {
|
||||
}
|
||||
}
|
||||
|
||||
struct NoopExecutor;
|
||||
impl Executor for NoopExecutor {
|
||||
struct NoopSpawner;
|
||||
impl Spawn for NoopSpawner {
|
||||
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
|
||||
Ok(())
|
||||
}
|
||||
@ -127,8 +127,8 @@ where
|
||||
let mut fut = PinBox::new(f(9));
|
||||
let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
|
||||
let waker = local_waker_from_nonlocal(counter.clone());
|
||||
let executor = &mut NoopExecutor;
|
||||
let cx = &mut Context::new(&waker, executor);
|
||||
let spawner = &mut NoopSpawner;
|
||||
let cx = &mut Context::new(&waker, spawner);
|
||||
|
||||
assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
|
||||
assert_eq!(Poll::Pending, fut.as_pin_mut().poll(cx));
|
||||
|
@ -23,7 +23,7 @@ use std::future::FutureObj;
|
||||
use std::task::{
|
||||
Context, Poll,
|
||||
Wake, Waker, LocalWaker,
|
||||
Executor, SpawnObjError,
|
||||
Spawn, SpawnObjError,
|
||||
local_waker, local_waker_from_nonlocal,
|
||||
};
|
||||
|
||||
@ -42,9 +42,9 @@ impl Wake for Counter {
|
||||
}
|
||||
}
|
||||
|
||||
struct NoopExecutor;
|
||||
struct NoopSpawner;
|
||||
|
||||
impl Executor for NoopExecutor {
|
||||
impl Spawn for NoopSpawner {
|
||||
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
|
||||
Ok(())
|
||||
}
|
||||
@ -59,7 +59,7 @@ impl Future for MyFuture {
|
||||
cx.waker().wake();
|
||||
cx.waker().wake();
|
||||
cx.local_waker().wake();
|
||||
cx.executor().spawn_obj(PinBox::new(MyFuture).into()).unwrap();
|
||||
cx.spawner().spawn_obj(PinBox::new(MyFuture).into()).unwrap();
|
||||
Poll::Ready(())
|
||||
}
|
||||
}
|
||||
@ -70,8 +70,8 @@ fn test_local_waker() {
|
||||
nonlocal_wakes: AtomicUsize::new(0),
|
||||
});
|
||||
let waker = unsafe { local_waker(counter.clone()) };
|
||||
let executor = &mut NoopExecutor;
|
||||
let cx = &mut Context::new(&waker, executor);
|
||||
let spawner = &mut NoopSpawner;
|
||||
let cx = &mut Context::new(&waker, spawner);
|
||||
assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
|
||||
assert_eq!(1, counter.local_wakes.load(atomic::Ordering::SeqCst));
|
||||
assert_eq!(2, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
|
||||
@ -83,8 +83,8 @@ fn test_local_as_nonlocal_waker() {
|
||||
nonlocal_wakes: AtomicUsize::new(0),
|
||||
});
|
||||
let waker: LocalWaker = local_waker_from_nonlocal(counter.clone());
|
||||
let executor = &mut NoopExecutor;
|
||||
let cx = &mut Context::new(&waker, executor);
|
||||
let spawner = &mut NoopSpawner;
|
||||
let cx = &mut Context::new(&waker, spawner);
|
||||
assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
|
||||
assert_eq!(0, counter.local_wakes.load(atomic::Ordering::SeqCst));
|
||||
assert_eq!(3, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
|
||||
|
Loading…
x
Reference in New Issue
Block a user