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;
}
#[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> {
issue = "50547")]
use fmt;
-use super::{Executor, Waker, LocalWaker};
+use super::{Spawn, Waker, LocalWaker};
/// Information about the currently-running task.
///
/// 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> {
}
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.
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,
}
}
}
+++ /dev/null
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(feature = "futures_api",
- reason = "futures in libcore are unstable",
- issue = "50547")]
-
-use fmt;
-use future::{FutureObj, LocalFutureObj};
-
-/// A 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 {
- /// Spawns a new task with the given future. The future will be polled until
- /// completion.
- ///
- /// # Errors
- ///
- /// The executor may be unable to spawn tasks, either because it has
- /// been shut down or is resource-constrained.
- fn spawn_obj(
- &mut self,
- future: FutureObj<'static, ()>,
- ) -> Result<(), SpawnObjError>;
-
- /// Determines whether the executor is able to spawn new tasks.
- ///
- /// # Returns
- ///
- /// An `Ok` return means the executor is *likely* (but not guaranteed)
- /// to accept a subsequent spawn attempt. Likewise, an `Err` return
- /// means that `spawn` is likely, but not guaranteed, to yield an error.
- #[inline]
- fn status(&self) -> Result<(), SpawnErrorKind> {
- Ok(())
- }
-}
-
-/// Provides the reason that an executor was unable to spawn.
-pub struct SpawnErrorKind {
- _hidden: (),
-}
-
-impl fmt::Debug for SpawnErrorKind {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_tuple("SpawnErrorKind")
- .field(&"shutdown")
- .finish()
- }
-}
-
-impl SpawnErrorKind {
- /// Spawning is failing because the executor has been shut down.
- pub fn shutdown() -> SpawnErrorKind {
- SpawnErrorKind { _hidden: () }
- }
-
- /// Check whether this error is the `shutdown` error.
- pub fn is_shutdown(&self) -> bool {
- true
- }
-}
-
-/// The result of a failed spawn
-#[derive(Debug)]
-pub struct SpawnObjError {
- /// The kind of error
- pub kind: SpawnErrorKind,
-
- /// The future for which spawning inside a task was attempted
- pub future: FutureObj<'static, ()>,
-}
-
-/// The result of a failed spawn
-#[derive(Debug)]
-pub struct SpawnLocalObjError {
- /// The kind of error
- pub kind: SpawnErrorKind,
-
- /// The future for which spawning inside a task was attempted
- pub future: LocalFutureObj<'static, ()>,
-}
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;
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![unstable(feature = "futures_api",
+ reason = "futures in libcore are unstable",
+ issue = "50547")]
+
+use fmt;
+use future::{FutureObj, LocalFutureObj};
+
+/// Spawns tasks that poll futures to completion onto its associated task
+/// 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.
+ ///
+ /// # Errors
+ ///
+ /// The executor may be unable to spawn tasks, either because it has
+ /// been shut down or is resource-constrained.
+ fn spawn_obj(
+ &mut self,
+ future: FutureObj<'static, ()>,
+ ) -> Result<(), SpawnObjError>;
+
+ /// Determines whether the executor is able to spawn new tasks.
+ ///
+ /// # Returns
+ ///
+ /// An `Ok` return means the executor is *likely* (but not guaranteed)
+ /// to accept a subsequent spawn attempt. Likewise, an `Err` return
+ /// means that `spawn` is likely, but not guaranteed, to yield an error.
+ #[inline]
+ fn status(&self) -> Result<(), SpawnErrorKind> {
+ Ok(())
+ }
+}
+
+/// Provides the reason that an executor was unable to spawn.
+pub struct SpawnErrorKind {
+ _hidden: (),
+}
+
+impl fmt::Debug for SpawnErrorKind {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_tuple("SpawnErrorKind")
+ .field(&"shutdown")
+ .finish()
+ }
+}
+
+impl SpawnErrorKind {
+ /// Spawning is failing because the executor has been shut down.
+ pub fn shutdown() -> SpawnErrorKind {
+ SpawnErrorKind { _hidden: () }
+ }
+
+ /// Check whether this error is the `shutdown` error.
+ pub fn is_shutdown(&self) -> bool {
+ true
+ }
+}
+
+/// The result of a failed spawn
+#[derive(Debug)]
+pub struct SpawnObjError {
+ /// The kind of error
+ pub kind: SpawnErrorKind,
+
+ /// The future for which spawning inside a task was attempted
+ pub future: FutureObj<'static, ()>,
+}
+
+/// The result of a failed spawn
+#[derive(Debug)]
+pub struct SpawnLocalObjError {
+ /// The kind of error
+ pub kind: SpawnErrorKind,
+
+ /// The future for which spawning inside a task was attempted
+ pub future: LocalFutureObj<'static, ()>,
+}
use std::future::FutureObj;
use std::task::{
Context, Poll, Wake,
- Executor, SpawnObjError,
+ Spawn, SpawnObjError,
local_waker_from_nonlocal,
};
}
}
-struct NoopExecutor;
-impl Executor for NoopExecutor {
+struct NoopSpawner;
+impl Spawn for NoopSpawner {
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
Ok(())
}
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));
use std::task::{
Context, Poll,
Wake, Waker, LocalWaker,
- Executor, SpawnObjError,
+ Spawn, SpawnObjError,
local_waker, local_waker_from_nonlocal,
};
}
}
-struct NoopExecutor;
+struct NoopSpawner;
-impl Executor for NoopExecutor {
+impl Spawn for NoopSpawner {
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
Ok(())
}
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(())
}
}
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));
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));