diff --git a/Cargo.toml b/Cargo.toml
index 7ba636a554..6f0d5e522c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,6 +9,5 @@ members = [
# "futures-macro-async",
# "futures-macro-await",
"futures-sink",
-# "futures-stable",
"futures-util",
]
diff --git a/futures-channel/src/lib.rs b/futures-channel/src/lib.rs
index 7fdf3eb739..5a9cedfc81 100644
--- a/futures-channel/src/lib.rs
+++ b/futures-channel/src/lib.rs
@@ -3,7 +3,7 @@
//! This crate provides channels that can be used to communicate between
//! asynchronous tasks.
-#![feature(pin, arbitrary_self_types)]
+#![feature(pin, arbitrary_self_types, futures_api)]
#![deny(missing_docs, missing_debug_implementations)]
#![doc(html_root_url = "https://docs.rs/futures-channel/0.2.0")]
diff --git a/futures-core/src/executor.rs b/futures-core/src/executor.rs
index 87af8d8aaa..f505bbc47e 100644
--- a/futures-core/src/executor.rs
+++ b/futures-core/src/executor.rs
@@ -1,61 +1,4 @@
//! Executors.
-use task::TaskObj;
+pub use core::task::{Executor, SpawnErrorKind, SpawnObjError};
-/// A task executor.
-///
-/// A *task* is a `()`-producing future that runs at the top level, and will
-/// be `poll`ed until completion. It's also the unit at which wake-up
-/// notifications occur. Executors, such as thread pools, allow tasks to be
-/// spawned and are responsible for putting tasks onto ready queues when
-/// they are woken up, and polling them when they are ready.
-pub trait Executor {
- /// Spawn the given task object, polling it 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, task: TaskObj) -> Result<(), SpawnObjError>;
-
- /// Determine 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.
- fn status(&self) -> Result<(), SpawnErrorKind> {
- Ok(())
- }
-
- // TODO: downcasting hooks
-}
-
-/// Provides the reason that an executor was unable to spawn.
-#[derive(Debug)]
-pub struct SpawnErrorKind {
- _a: ()
-}
-
-impl SpawnErrorKind {
- /// Spawning is failing because the executor has been shut down.
- pub fn shutdown() -> SpawnErrorKind {
- SpawnErrorKind { _a: () }
- }
-
- /// Check whether this error is the `shutdown` error.
- pub fn is_shutdown() -> bool {
- true
- }
-}
-
-/// The result of a failed spawn
-#[derive(Debug)]
-pub struct SpawnObjError {
- /// The kind of error
- pub kind: SpawnErrorKind,
-
- /// The task for which spawning was attempted
- pub task: TaskObj,
-}
diff --git a/futures-core/src/future/either.rs b/futures-core/src/future/either.rs
index f8d0feea59..20c694b736 100644
--- a/futures-core/src/future/either.rs
+++ b/futures-core/src/future/either.rs
@@ -1,24 +1,24 @@
-use {task, Future, Stream, Poll};
+use {task, Stream, Poll};
use core::mem::PinMut;
use either::Either;
-impl Future for Either
- where A: Future,
- B: Future
-{
- type Output = A::Output;
+// impl Future for Either
+// where A: Future,
+// B: Future
+// {
+// type Output = A::Output;
- fn poll(self: PinMut, cx: &mut task::Context) -> Poll {
- unsafe {
- match PinMut::get_mut(self) {
- Either::Left(a) => PinMut::new_unchecked(a).poll(cx),
- Either::Right(b) => PinMut::new_unchecked(b).poll(cx),
- }
- }
- }
-}
+// fn poll(self: PinMut, cx: &mut task::Context) -> Poll {
+// unsafe {
+// match PinMut::get_mut(self) {
+// Either::Left(a) => PinMut::new_unchecked(a).poll(cx),
+// Either::Right(b) => PinMut::new_unchecked(b).poll(cx),
+// }
+// }
+// }
+// }
impl Stream for Either
where A: Stream,
diff --git a/futures-core/src/future/mod.rs b/futures-core/src/future/mod.rs
index 854c3be407..8b12a9b46c 100644
--- a/futures-core/src/future/mod.rs
+++ b/futures-core/src/future/mod.rs
@@ -12,106 +12,10 @@ pub use self::option::FutureOption;
#[cfg(feature = "either")]
mod either;
-/// A future represents an asychronous computation.
-///
-/// A future is a value that may not have finished computing yet. This kind of
-/// "asynchronous value" makes it possible for a thread to continue doing useful
-/// work while it waits for the value to become available.
-///
-/// The ergonomics and implementation of the `Future` trait are very similar to
-/// the `Iterator` trait in that there is just one method you need to
-/// implement, but you get a whole lot of others for free as a result. These
-/// other methods allow you to chain together large computations based on
-/// futures, which will automatically handle asynchrony for you.
-///
-/// # The `poll` method
-///
-/// The core method of future, `poll`, *attempts* to resolve the future into a
-/// final value. This method does not block if the value is not ready. Instead,
-/// the current task is scheduled to be woken up when it's possible to make
-/// further progress by `poll`ing again. The wake up is performed using
-/// `cx.waker()`, a handle for waking up the current task.
-///
-/// When using a future, you generally won't call `poll` directly, but instead
-/// use combinators to build up asynchronous computations. A complete
-/// computation can then be spawned onto an
-/// [executor](../futures_core/executor/trait.Executor.html) as a new, independent
-/// task that will automatically be `poll`ed to completion.
-///
-/// # Combinators
-///
-/// Like iterators, futures provide a large number of combinators to work with
-/// futures to express computations in a much more natural method than
-/// scheduling a number of callbacks. As with iterators, the combinators are
-/// zero-cost: they compile away. You can find the combinators in the
-/// [future-util](https://docs.rs/futures-util) crate.
-pub trait Future {
- /// The result of the future
- type Output;
-
- /// Attempt to resolve the future to a final value, registering
- /// the current task for wakeup if the value is not yet available.
- ///
- /// # Return value
- ///
- /// This function returns:
- ///
- /// - `Poll::Pending` if the future is not ready yet
- /// - `Poll::Ready(val)` with the result `val` of this future if it finished
- /// successfully.
- ///
- /// Once a future has finished, clients should not `poll` it again.
- ///
- /// When a future is not ready yet, `poll` returns
- /// [`Poll::Pending`](::Poll). The future will *also* register the
- /// interest of the current task in the value being produced. For example,
- /// if the future represents the availability of data on a socket, then the
- /// task is recorded so that when data arrives, it is woken up (via
- /// [`cx.waker()`](::task::Context::waker). Once a task has been woken up,
- /// it should attempt to `poll` the future again, which may or may not
- /// produce a final value.
- ///
- /// Note that if `Pending` is returned it only means that the *current* task
- /// (represented by the argument `cx`) will receive a notification. Tasks
- /// from previous calls to `poll` will *not* receive notifications.
- ///
- /// # Runtime characteristics
- ///
- /// Futures alone are *inert*; they must be *actively* `poll`ed to make
- /// progress, meaning that each time the current task is woken up, it should
- /// actively re-`poll` pending futures that it still has an interest in.
- /// Usually this is done by building up a large computation as a single
- /// future (using combinators), then spawning that future as a *task* onto
- /// an [executor](../futures_core/executor/trait.Executor.html). Executors
- /// ensure that each task is `poll`ed every time a future internal to that
- /// task is ready to make progress.
- ///
- /// The `poll` function is not called repeatedly in a tight loop for
- /// futures, but only whenever the future itself is ready, as signaled via
- /// [`cx.waker()`](::task::Context::waker). If you're familiar with the
- /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
- /// typically do *not* suffer the same problems of "all wakeups must poll
- /// all events"; they are more like `epoll(4)`.
- ///
- /// An implementation of `poll` should strive to return quickly, and must
- /// *never* block. Returning quickly prevents unnecessarily clogging up
- /// threads or event loops. If it is known ahead of time that a call to
- /// `poll` may end up taking awhile, the work should be offloaded to a
- /// thread pool (or something similar) to ensure that `poll` can return
- /// quickly.
- ///
- /// # Panics
- ///
- /// Once a future has completed (returned `Ready` from `poll`),
- /// then any future calls to `poll` may panic, block forever, or otherwise
- /// cause bad behavior. The `Future` trait itself provides no guarantees
- /// about the behavior of `poll` after a future has completed.
- ///
- /// Callers who may call `poll` too many times may want to consider using
- /// the `fuse` adaptor which defines the behavior of `poll`, but comes with
- /// a little bit of extra cost.
- fn poll(self: PinMut, cx: &mut task::Context) -> Poll;
+pub use core::future::Future;
+/// Will probably merge with futures_util::FutureExt
+pub trait CoreFutureExt: Future {
/// A convenience for calling `Future::poll` on `Unpin` future types.
fn poll_unpin(&mut self, cx: &mut task::Context) -> Poll
where Self: Unpin
@@ -120,50 +24,8 @@ pub trait Future {
}
}
-impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F {
- type Output = F::Output;
-
- fn poll(mut self: PinMut, cx: &mut task::Context) -> Poll {
- F::poll(PinMut::new(&mut **self), cx)
- }
-}
-
-impl<'a, F: ?Sized + Future> Future for PinMut<'a, F> {
- type Output = F::Output;
-
- fn poll(mut self: PinMut, cx: &mut task::Context) -> Poll {
- F::poll((*self).reborrow(), cx)
- }
-}
-
-if_std! {
- use std::boxed::{Box, PinBox};
-
- impl<'a, F: ?Sized + Future + Unpin> Future for Box {
- type Output = F::Output;
-
- fn poll(mut self: PinMut, cx: &mut task::Context) -> Poll {
- (**self).poll_unpin(cx)
- }
- }
-
- impl<'a, F: ?Sized + Future> Future for PinBox {
- type Output = F::Output;
-
- fn poll(mut self: PinMut, cx: &mut task::Context) -> Poll {
- self.as_pin_mut().poll(cx)
- }
- }
-
- impl<'a, F: Future> Future for ::std::panic::AssertUnwindSafe {
- type Output = F::Output;
-
- fn poll(mut self: PinMut, cx: &mut task::Context) -> Poll {
- unsafe { pinned_field!(self, 0).poll(cx) }
- }
- }
-}
-
+impl CoreFutureExt for T where T: Future {}
+
/// A convenience for futures that return `Result` values that includes
/// a variety of adapters tailored to such futures.
pub trait TryFuture {
diff --git a/futures-core/src/lib.rs b/futures-core/src/lib.rs
index 04cac38426..546f685772 100644
--- a/futures-core/src/lib.rs
+++ b/futures-core/src/lib.rs
@@ -1,6 +1,7 @@
//! Core traits and types for asynchronous operations in Rust.
#![feature(pin, arbitrary_self_types)]
+#![feature(futures_api)]
#![no_std]
#![deny(missing_docs, missing_debug_implementations, warnings)]
diff --git a/futures-core/src/poll.rs b/futures-core/src/poll.rs
index 973755825c..47bbcee62d 100644
--- a/futures-core/src/poll.rs
+++ b/futures-core/src/poll.rs
@@ -1,3 +1,6 @@
+
+pub use core::task::Poll;
+
/// A macro for extracting the successful type of a `Poll>`.
///
/// This macro bakes in propagation of `Pending` and `Err` signals by returning early.
@@ -38,73 +41,3 @@ macro_rules! ready {
$crate::Poll::Pending => return $crate::Poll::Pending,
})
}
-
-/// Indicates whether a value is available, or if the current task has been
-/// scheduled for later wake-up instead.
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum Poll {
- /// Represents that a value is immediately ready.
- Ready(T),
-
- /// Represents that a value is not ready yet.
- ///
- /// When a function returns `Pending`, the function *must* also
- /// ensure that the current task is scheduled to be awoken when
- /// progress can be made.
- Pending,
-}
-
-impl Poll {
- /// Change the ready value of this `Poll` with the closure provided
- pub fn map(self, f: F) -> Poll
- where F: FnOnce(T) -> U
- {
- match self {
- Poll::Ready(t) => Poll::Ready(f(t)),
- Poll::Pending => Poll::Pending,
- }
- }
-
- /// Returns whether this is `Poll::Ready`
- pub fn is_ready(&self) -> bool {
- match *self {
- Poll::Ready(_) => true,
- Poll::Pending => false,
- }
- }
-
- /// Returns whether this is `Poll::Pending`
- pub fn is_pending(&self) -> bool {
- !self.is_ready()
- }
-}
-
-impl Poll> {
- /// Change the success value of this `Poll` with the closure provided
- pub fn map_ok(self, f: F) -> Poll>
- where F: FnOnce(T) -> U
- {
- match self {
- Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
- Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
- Poll::Pending => Poll::Pending,
- }
- }
-
- /// Change the error value of this `Poll` with the closure provided
- pub fn map_err(self, f: F) -> Poll>
- where F: FnOnce(E) -> U
- {
- match self {
- Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
- Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
- Poll::Pending => Poll::Pending,
- }
- }
-}
-
-impl From for Poll {
- fn from(t: T) -> Poll {
- Poll::Ready(t)
- }
-}
diff --git a/futures-core/src/task/context.rs b/futures-core/src/task/context.rs
deleted file mode 100644
index 5672679cd2..0000000000
--- a/futures-core/src/task/context.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-use core::fmt;
-
-use executor::Executor;
-use task::{TaskObj, Waker};
-
-/// Information about the currently-running task.
-///
-/// Contexts are always tied to the stack, since they are set up specifically
-/// when performing a single `poll` step on a task.
-pub struct Context<'a> {
- waker: &'a Waker,
- executor: &'a mut Executor,
-}
-
-impl<'a> Context<'a> {
- /// Create a new task context.
- ///
- /// Task contexts are equipped with:
- /// - A means of waking the task
- /// - A means of spawning new tasks, i.e. an [executor]()
- pub fn new(waker: &'a Waker, executor: &'a mut E) -> Context<'a>
- where E: Executor
- {
- Context { waker, executor }
- }
-
- /// Get the default executor associated with this task.
- ///
- /// This method is useful primarily if you want to explicitly handle
- /// spawn failures.
- pub fn executor(&mut self) -> &mut Executor {
- self.executor
- }
-
- /// Produce a context like the current one, but using the given executor
- /// instead.
- ///
- /// This advanced method is primarily used when building "internal
- /// schedulers" within a task.
- pub fn with_executor<'b, E>(&'b mut self, executor: &'b mut E) -> Context<'b>
- where E: Executor
- {
- Context { waker: self.waker, executor }
- }
-
- /// Get the [`Waker`](::task::Waker) associated with the current task.
- ///
- /// The waker can subsequently be used to wake up the task when some
- /// event of interest has happened.
- pub fn waker(&self) -> &Waker {
- self.waker
- }
-
- /// 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.
- pub fn with_waker<'b>(&'b mut self, waker: &'b Waker) -> Context<'b> {
- Context { waker, executor: self.executor }
- }
-}
-
-impl<'a> fmt::Debug for Context<'a> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("Context")
- .finish()
- }
-}
-
-if_std! {
- use Future;
-
- impl<'a> Context<'a> {
- /// Spawn a future onto the default executor.
- ///
- /// # Panics
- ///
- /// This method will panic if the default executor is unable to spawn.
- ///
- /// To handle executor errors, use [executor()](self::Context::executor)
- /// instead.
- pub fn spawn(&mut self, f: F) where F: Future + 'static + Send {
- self.executor()
- .spawn_obj(TaskObj::new(f)).unwrap()
- }
- }
-}
diff --git a/futures-core/src/task/mod.rs b/futures-core/src/task/mod.rs
index d584335f61..557c174d7c 100644
--- a/futures-core/src/task/mod.rs
+++ b/futures-core/src/task/mod.rs
@@ -1,129 +1,40 @@
//! Task notification.
-use core::mem::{self, PinMut};
-use core::fmt;
+use Future;
-use {Future, Poll};
-
-mod wake;
-pub use self::wake::{UnsafeWake, Waker};
+pub use core::task::{UnsafeWake, Waker};
#[cfg(feature = "std")]
-pub use self::wake::Wake;
+pub use std::task::Wake;
-mod context;
-pub use self::context::Context;
+pub use core::task::Context;
#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))]
mod atomic_waker;
#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))]
pub use self::atomic_waker::AtomicWaker;
-/// A custom trait object for polling tasks, roughly akin to
-/// `Box + Send>`.
-pub struct TaskObj {
- ptr: *mut (),
- poll: unsafe fn(*mut (), &mut Context) -> Poll<()>,
- drop: unsafe fn(*mut ()),
-}
-
-impl fmt::Debug for TaskObj {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("TakObj")
- .finish()
- }
-}
-
-unsafe impl Send for TaskObj {}
-unsafe impl Sync for TaskObj {}
-
-/// A custom implementation of a task trait object for `TaskObj`, providing
-/// a hand-rolled vtable.
-///
-/// This custom representation is typically used only in `no_std` contexts,
-/// where the default `Box`-based implementation is not available.
-///
-/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
-/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
-/// called.
-pub unsafe trait UnsafePoll: Send + 'static {
- /// Convert a owned instance into a (conceptually owned) void pointer.
- fn into_raw(self) -> *mut ();
-
- /// Poll the task represented by the given void pointer.
- ///
- /// # Safety
- ///
- /// The trait implementor must guarantee that it is safe to repeatedly call
- /// `poll` with the result of `into_raw` until `drop` is called; such calls
- /// are not, however, allowed to race with each other or with calls to `drop`.
- unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()>;
-
- /// Drops the task represented by the given void pointer.
- ///
- /// # Safety
- ///
- /// The trait implementor must guarantee that it is safe to call this
- /// function once per `into_raw` invocation; that call cannot race with
- /// other calls to `drop` or `poll`.
- unsafe fn drop(task: *mut ());
-}
-
-impl TaskObj {
- /// Create a `TaskObj` from a custom trait object representation.
- pub fn from_poll_task(t: T) -> TaskObj {
- TaskObj {
- ptr: t.into_raw(),
- poll: T::poll,
- drop: T::drop,
- }
- }
-
- /// Poll the task.
- ///
- /// The semantics here are identical to that for futures, but unlike
- /// futures only an `&mut self` reference is needed here.
- pub fn poll_task(&mut self, cx: &mut Context) -> Poll<()> {
- unsafe {
- (self.poll)(self.ptr, cx)
- }
- }
-}
-
-impl Drop for TaskObj {
- fn drop(&mut self) {
- unsafe {
- (self.drop)(self.ptr)
- }
- }
-}
+pub use core::task::{TaskObj, UnsafeTask};
if_std! {
- use std::boxed::Box;
-
- unsafe impl + Send + 'static> UnsafePoll for Box {
- fn into_raw(self) -> *mut () {
- unsafe {
- mem::transmute(self)
- }
- }
-
- unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()> {
- let ptr: *mut F = mem::transmute(task);
- let pin: PinMut = PinMut::new_unchecked(&mut *ptr);
- pin.poll(cx)
- }
-
- unsafe fn drop(task: *mut ()) {
- let ptr: *mut F = mem::transmute(task);
- let boxed = Box::from_raw(ptr);
- drop(boxed)
- }
+ use std::boxed::PinBox;
+
+ /// Extension trait for `Context`, adding methods that require allocation.
+ pub trait ContextExt {
+ /// Spawn a future onto the default executor.
+ ///
+ /// # Panics
+ ///
+ /// This method will panic if the default executor is unable to spawn.
+ ///
+ /// To handle executor errors, use [executor()](self::Context::executor)
+ /// instead.
+ fn spawn(&mut self, f: F) where F: Future + 'static + Send;
}
- impl TaskObj {
- /// Create a new `TaskObj` by boxing the given future.
- pub fn new + Send + 'static>(f: F) -> TaskObj {
- TaskObj::from_poll_task(Box::new(f))
+ impl<'a> ContextExt for Context<'a> {
+ fn spawn(&mut self, f: F) where F: Future + 'static + Send {
+ self.executor()
+ .spawn_obj(TaskObj::new(PinBox::new(f))).unwrap()
}
}
}
diff --git a/futures-core/src/task/wake.rs b/futures-core/src/task/wake.rs
deleted file mode 100644
index 0be3f36e7c..0000000000
--- a/futures-core/src/task/wake.rs
+++ /dev/null
@@ -1,235 +0,0 @@
-use core::fmt;
-
-/// An unsafe trait for implementing custom memory management for a
-/// [`Waker`](::task::Waker).
-///
-/// A [`Waker`](::task::Waker) is a cloneable trait object for `Wake`, and is
-/// most often essentially just `Arc`. However, in some contexts
-/// (particularly `no_std`), it's desirable to avoid `Arc` in favor of some
-/// custom memory management strategy. This trait is designed to allow for such
-/// customization.
-///
-/// A default implementation of the `UnsafeWake` trait is provided for the
-/// `Arc` type in the standard library. If the `std` feature of this crate
-/// is not available however, you'll be required to implement your own
-/// instance of this trait to pass it into `Waker::new`.
-///
-/// # Unsafety
-///
-/// This trait manually encodes the memory management of the underlying trait
-/// object. Implementors of this trait must guarantee:
-///
-/// * Calls to `clone_raw` produce uniquely owned `Waker` handles. These handles
-/// should be independently usable and droppable.
-///
-/// * Calls to `drop_raw` work with `self` as a raw pointer, deallocating
-/// resources associated with it. This is a pretty unsafe operation as it's
-/// invalidating the `self` pointer, so extreme care needs to be taken.
-///
-/// In general it's recommended to review the trait documentation as well as the
-/// implementation for `Arc` in this crate before attempting a custom
-/// implementation.
-pub unsafe trait UnsafeWake {
- /// Creates a new `Waker` from this instance of `UnsafeWake`.
- ///
- /// This function will create a new uniquely owned handle that under the
- /// hood references the same notification instance. In other words calls
- /// to `wake` on the returned handle should be equivalent to calls to
- /// `wake` on this handle.
- ///
- /// # Unsafety
- ///
- /// This is also unsafe to call because it's asserting the `UnsafeWake`
- /// value is in a consistent state, i.e. hasn't been dropped.
- unsafe fn clone_raw(&self) -> Waker;
-
- /// Drops this instance of `UnsafeWake`, deallocating resources
- /// associated with it.
- ///
- /// This method is intended to have a signature such as:
- ///
- /// ```ignore
- /// fn drop_raw(self: *mut Self);
- /// ```
- ///
- /// Unfortunately in Rust today that signature is not object safe.
- /// Nevertheless it's recommended to implement this function *as if* that
- /// were its signature. As such it is not safe to call on an invalid
- /// pointer, nor is the validity of the pointer guaranteed after this
- /// function returns.
- ///
- /// # Unsafety
- ///
- /// This is also unsafe to call because it's asserting the `UnsafeWake`
- /// value is in a consistent state, i.e. hasn't been dropped
- unsafe fn drop_raw(&self);
-
- /// Indicates that the associated task is ready to make progress and should
- /// be `poll`ed.
- ///
- /// Executors generally maintain a queue of "ready" tasks; `wake` should place
- /// the associated task onto this queue.
- ///
- /// # Panics
- ///
- /// Implementations should avoid panicking, but clients should also be prepared
- /// for panics.
- ///
- /// # Unsafety
- ///
- /// This is also unsafe to call because it's asserting the `UnsafeWake`
- /// value is in a consistent state, i.e. hasn't been dropped
- unsafe fn wake(&self);
-}
-
-/// A `Waker` is a handle for waking up a task by notifying its executor that it
-/// is ready to be run.
-///
-/// This handle contains a trait object pointing to an instance of the `Wake`
-/// trait, allowing notifications to get routed through it. Usually `Waker`
-/// instances are provided by an executor.
-///
-/// If you're implementing an executor, the recommended way to create a `Waker`
-/// is via `Waker::from` applied to an `Arc` value where `T: Wake`. The
-/// unsafe `new` constructor should be used only in niche, `no_std` settings.
-pub struct Waker {
- inner: *const UnsafeWake,
-}
-
-unsafe impl Send for Waker {}
-unsafe impl Sync for Waker {}
-
-impl Waker {
- /// Constructs a new `Waker` directly.
- ///
- /// Note that most code will not need to call this. Implementers of the
- /// `UnsafeWake` trait will typically provide a wrapper that calls this
- /// but you otherwise shouldn't call it directly.
- ///
- /// If you're working with the standard library then it's recommended to
- /// use the `Waker::from` function instead which works with the safe
- /// `Arc` type and the safe `Wake` trait.
- #[inline]
- pub unsafe fn new(inner: *const UnsafeWake) -> Waker {
- Waker { inner: inner }
- }
-
- /// Wake up the task associated with this `Waker`.
- pub fn wake(&self) {
- unsafe { (*self.inner).wake() }
- }
-
- /// Returns whether or not this `Waker` and `other` awaken the same task.
- ///
- /// This function works on a best-effort basis, and may return false even
- /// when the `Waker`s would awaken the same task. However, if this function
- /// returns true, it is guaranteed that the `Waker`s will awaken the same
- /// task.
- ///
- /// This function is primarily used for optimization purposes.
- pub fn will_wake(&self, other: &Waker) -> bool {
- self.inner == other.inner
- }
-}
-
-impl Clone for Waker {
- #[inline]
- fn clone(&self) -> Self {
- unsafe {
- (*self.inner).clone_raw()
- }
- }
-}
-
-impl fmt::Debug for Waker {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("Waker")
- .finish()
- }
-}
-
-impl Drop for Waker {
- fn drop(&mut self) {
- unsafe {
- (*self.inner).drop_raw()
- }
- }
-}
-
-if_std! {
- use std::mem;
- use std::ptr;
- use std::sync::Arc;
- use core::marker::PhantomData;
-
- /// A way of waking up a specific task.
- ///
- /// Any task executor must provide a way of signaling that a task it owns
- /// is ready to be `poll`ed again. Executors do so by implementing this trait.
- ///
- /// Note that, rather than working directly with `Wake` trait objects, this
- /// library instead uses a custom [`Waker`](::task::Waker) to allow for
- /// customization of memory management.
- pub trait Wake: Send + Sync {
- /// Indicates that the associated task is ready to make progress and should
- /// be `poll`ed.
- ///
- /// Executors generally maintain a queue of "ready" tasks; `wake` should place
- /// the associated task onto this queue.
- ///
- /// # Panics
- ///
- /// Implementations should avoid panicking, but clients should also be prepared
- /// for panics.
- fn wake(arc_self: &Arc);
- }
-
- // Safe implementation of `UnsafeWake` for `Arc` in the standard library.
- //
- // Note that this is a very unsafe implementation! The crucial pieces is that
- // these two values are considered equivalent:
- //
- // * Arc
- // * *const ArcWrapped
- //
- // We don't actually know the layout of `ArcWrapped` as it's an
- // implementation detail in the standard library. We can work, though, by
- // casting it through and back an `Arc`.
- //
- // This also means that you won't actually find `UnsafeWake for Arc`
- // because it's the wrong level of indirection. These methods are sort of
- // receiving Arc, but not an owned version. It's... complicated. We may be
- // one of the first users of unsafe trait objects!
-
- struct ArcWrapped(PhantomData);
-
- unsafe impl UnsafeWake for ArcWrapped {
- unsafe fn clone_raw(&self) -> Waker {
- let me: *const ArcWrapped = self;
- let arc = (*(&me as *const *const ArcWrapped as *const Arc)).clone();
- Waker::from(arc)
- }
-
- unsafe fn drop_raw(&self) {
- let mut me: *const ArcWrapped = self;
- let me = &mut me as *mut *const ArcWrapped as *mut Arc;
- ptr::drop_in_place(me);
- }
-
- unsafe fn wake(&self) {
- let me: *const ArcWrapped = self;
- T::wake(&*(&me as *const *const ArcWrapped as *const Arc))
- }
- }
-
- impl From> for Waker
- where T: Wake + 'static,
- {
- fn from(rc: Arc) -> Waker {
- unsafe {
- let ptr = mem::transmute::, *const ArcWrapped>(rc);
- Waker::new(ptr)
- }
- }
- }
-}
diff --git a/futures-io/src/lib.rs b/futures-io/src/lib.rs
index b5b8dc6864..9e3dc68561 100644
--- a/futures-io/src/lib.rs
+++ b/futures-io/src/lib.rs
@@ -8,6 +8,8 @@
#![deny(missing_docs, missing_debug_implementations)]
#![doc(html_rnoot_url = "https://docs.rs/futures-io/0.2.0")]
+#![feature(futures_api)]
+
macro_rules! if_std {
($($i:item)*) => ($(
#[cfg(feature = "std")]
diff --git a/futures-sink/src/lib.rs b/futures-sink/src/lib.rs
index d29660776c..ea3cf03814 100644
--- a/futures-sink/src/lib.rs
+++ b/futures-sink/src/lib.rs
@@ -7,7 +7,7 @@
#![deny(missing_docs, missing_debug_implementations)]
#![doc(html_root_url = "https://docs.rs/futures-sink/0.2.0")]
-#![feature(pin, arbitrary_self_types)]
+#![feature(pin, arbitrary_self_types, futures_api)]
#[cfg(feature = "std")]
extern crate std;
diff --git a/futures-stable/Cargo.toml b/futures-stable/Cargo.toml
deleted file mode 100644
index b71a5b9412..0000000000
--- a/futures-stable/Cargo.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-[package]
-name = "futures-stable"
-description = "futures which support internal references"
-version = "0.2.0"
-authors = ["boats "]
-license = "MIT OR Apache-2.0"
-repository = "https://github.com/rust-lang-nursery/futures-rs"
-
-[dependencies.futures-core]
-path = "../futures-core"
-version = "0.2.0"
-default-features = false
-
-[dependencies.futures-executor]
-path = "../futures-executor"
-version = "0.2.0"
-default-features = false
-
-[features]
-nightly = ["futures-core/nightly"]
-std = ["futures-core/std", "futures-executor/std"]
-default = ["std"]
diff --git a/futures-stable/src/executor.rs b/futures-stable/src/executor.rs
deleted file mode 100644
index 903d170193..0000000000
--- a/futures-stable/src/executor.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use std::boxed::PinBox;
-
-use futures_core::{Future, Never};
-use futures_core::executor::{Executor, SpawnError};
-use futures_executor::{ThreadPool, LocalPool, LocalExecutor};
-
-use StableFuture;
-use UnsafePinMut;
-
-pub trait StableExecutor: Executor {
- fn spawn_pinned(&mut self, f: PinBox + Send>) -> Result<(), SpawnError>;
-}
-
-impl StableExecutor for ThreadPool {
- fn spawn_pinned(&mut self, f: PinBox + Send>) -> Result<(), SpawnError> {
- unsafe { self.spawn(PinBox::unpin(f)) }
- }
-}
-
-impl StableExecutor for LocalExecutor {
- fn spawn_pinned(&mut self, f: PinBox + Send>) -> Result<(), SpawnError> {
- unsafe { self.spawn(PinBox::unpin(f)) }
- }
-}
-
-pub fn block_on_stable(f: F) -> Result {
- let mut pool = LocalPool::new();
- let mut exec = pool.executor();
-
- // run our main future to completion
- let res = pool.run_until(unsafe { UnsafePinMut::new(f) }, &mut exec);
- // run any remainingspawned tasks to completion
- pool.run(&mut exec);
-
- res
-}
diff --git a/futures-stable/src/lib.rs b/futures-stable/src/lib.rs
deleted file mode 100644
index 9c514cb679..0000000000
--- a/futures-stable/src/lib.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-#![no_std]
-#![cfg_attr(feature = "nightly", feature(arbitrary_self_types))]
-#![cfg_attr(feature = "nightly", feature(pin))]
-
-macro_rules! if_nightly {
- ($($i:item)*) => ($(
- #[cfg(feature = "nightly")]
- $i
- )*)
-}
-
-if_nightly! {
- macro_rules! if_std {
- ($($i:item)*) => ($(
- #[cfg(feature = "std")]
- $i
- )*)
- }
-
- extern crate futures_core;
- extern crate futures_executor;
-
- use core::mem::PinMut;
- use futures_core::{Future, Stream, Poll, task};
-
- if_std! {
- extern crate std;
-
- mod executor;
- mod unsafe_pin;
-
- use std::boxed::PinBox;
-
- pub use executor::{StableExecutor, block_on_stable};
- use unsafe_pin::UnsafePinMut;
- }
-
- pub trait StableFuture {
- type Item;
- type Error;
-
- fn poll(self: PinMut, ctx: &mut task::Context) -> Poll;
-
- #[cfg(feature = "std")]
- fn pin<'a>(self) -> PinBox + Send + 'a>
- where Self: Send + Sized + 'a
- {
- PinBox::new(unsafe { UnsafePinMut::new(self) })
- }
-
- #[cfg(feature = "std")]
- fn pin_local<'a>(self) -> PinBox + 'a>
- where Self: Sized + 'a
- {
- PinBox::new(unsafe { UnsafePinMut::new(self) })
- }
- }
-
- impl StableFuture for F {
- type Item = F::Item;
- type Error = F::Error;
-
- fn poll(mut self: PinMut, ctx: &mut task::Context) -> Poll {
- F::poll(unsafe { PinMut::get_mut(&mut self) }, ctx)
- }
- }
-
- pub trait StableStream {
- type Item;
- type Error;
-
- fn poll_next(self: PinMut, ctx: &mut task::Context) -> Poll, Self::Error>;
-
- #[cfg(feature = "std")]
- fn pin<'a>(self) -> PinBox + Send + 'a>
- where Self: Send + Sized + 'a
- {
- PinBox::new(unsafe { UnsafePinMut::new(self) })
- }
-
- #[cfg(feature = "std")]
- fn pin_local<'a>(self) -> PinBox + 'a>
- where Self: Sized + 'a
- {
- PinBox::new(unsafe { UnsafePinMut::new(self) })
- }
- }
-
- impl StableStream for S {
- type Item = S::Item;
- type Error = S::Error;
-
- fn poll_next(mut self: PinMut, ctx: &mut task::Context) -> Poll, Self::Error> {
- S::poll_next(unsafe { PinMut::get_mut(&mut self) }, ctx)
- }
- }
-}
diff --git a/futures-stable/src/unsafe_pin.rs b/futures-stable/src/unsafe_pin.rs
deleted file mode 100644
index 8b164eaa38..0000000000
--- a/futures-stable/src/unsafe_pin.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-use core::mem::PinMut;
-use futures_core::{Future, Stream, Poll, task};
-
-use {StableFuture, StableStream};
-
-pub(crate) struct UnsafePinMut {
- inner: T,
-}
-
-impl UnsafePinMut {
- pub(crate) unsafe fn new(inner: T) -> UnsafePinMut {
- UnsafePinMut { inner }
- }
-}
-
-impl<'a, T: StableFuture> Future for UnsafePinMut {
- type Item = T::Item;
- type Error = T::Error;
- fn poll(&mut self, ctx: &mut task::Context) -> Poll {
- T::poll(unsafe { PinMut::new_unchecked(&mut self.inner) }, ctx)
- }
-}
-
-impl<'a, T: StableStream> Stream for UnsafePinMut {
- type Item = T::Item;
- type Error = T::Error;
- fn poll_next(&mut self, ctx: &mut task::Context) -> Poll, Self::Error> {
- T::poll_next(unsafe { PinMut::new_unchecked(&mut self.inner) }, ctx)
- }
-}
diff --git a/futures-util/src/lib.rs b/futures-util/src/lib.rs
index cb32a94538..3ee8b38801 100644
--- a/futures-util/src/lib.rs
+++ b/futures-util/src/lib.rs
@@ -1,7 +1,7 @@
//! Combinators and utilities for working with `Future`s, `Stream`s, `Sink`s,
//! and the `AsyncRead` and `AsyncWrite` traits.
-#![feature(pin, arbitrary_self_types)]
+#![feature(pin, arbitrary_self_types, futures_api)]
#![no_std]
#![deny(missing_docs, missing_debug_implementations, warnings)]