use core::mem::{self, PinMut};
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
use core::ptr::{self, NonNull, Unique};
-use core::task::{Context, Poll, UnsafeTask, TaskObj, LocalTaskObj};
+use core::task::{Context, Poll, UnsafeFutureObj, FutureObj, LocalFutureObj};
use core::convert::From;
use raw_vec::RawVec;
}
#[unstable(feature = "futures_api", issue = "50547")]
-unsafe impl<F: Future<Output = ()> + 'static> UnsafeTask for PinBox<F> {
+unsafe impl<T, F: Future<Output = T> + 'static> UnsafeFutureObj<T> for PinBox<F> {
fn into_raw(self) -> *mut () {
PinBox::into_raw(self) as *mut ()
}
- unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()> {
+ unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<T> {
let ptr = task as *mut F;
let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
pin.poll(cx)
}
#[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + Send + 'static> From<PinBox<F>> for TaskObj {
- fn from(boxed: PinBox<F>) -> Self {
- TaskObj::new(boxed)
+impl<T, F: Future<Output = T> + Send + 'static> Into<FutureObj<T>> for PinBox<F> {
+ fn into(self) -> FutureObj<T> {
+ FutureObj::new(self)
}
}
#[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + Send + 'static> From<Box<F>> for TaskObj {
- fn from(boxed: Box<F>) -> Self {
- TaskObj::new(PinBox::from(boxed))
+impl<T, F: Future<Output = T> + Send + 'static> Into<FutureObj<T>> for Box<F> {
+ fn into(self) -> FutureObj<T> {
+ FutureObj::new(PinBox::from(self))
}
}
#[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + 'static> From<PinBox<F>> for LocalTaskObj {
- fn from(boxed: PinBox<F>) -> Self {
- LocalTaskObj::new(boxed)
+impl<T, F: Future<Output = T> + 'static> Into<LocalFutureObj<T>> for PinBox<F> {
+ fn into(self) -> LocalFutureObj<T> {
+ LocalFutureObj::new(self)
}
}
#[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + 'static> From<Box<F>> for LocalTaskObj {
- fn from(boxed: Box<F>) -> Self {
- LocalTaskObj::new(PinBox::from(boxed))
+impl<T, F: Future<Output = T> + 'static> Into<LocalFutureObj<T>> for Box<F> {
+ fn into(self) -> LocalFutureObj<T> {
+ LocalFutureObj::new(PinBox::from(self))
}
}
issue = "50547")]
use fmt;
-use super::{TaskObj, LocalTaskObj};
+use super::{FutureObj, LocalFutureObj};
/// A task executor.
///
///
/// 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>;
+ fn spawn_obj(&mut self, task: FutureObj<()>) -> Result<(), SpawnObjError>;
/// Determine whether the executor is able to spawn new tasks.
///
pub kind: SpawnErrorKind,
/// The task for which spawning was attempted
- pub task: TaskObj,
+ pub task: FutureObj<()>,
}
/// The result of a failed spawn
pub kind: SpawnErrorKind,
/// The task for which spawning was attempted
- pub task: LocalTaskObj,
+ pub task: LocalFutureObj<()>,
}
--- /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::Future;
+use marker::PhantomData;
+use mem::PinMut;
+use task::{Context, Poll};
+
+/// A custom trait object for polling futures, roughly akin to
+/// `Box<dyn Future<Output = T>>`.
+/// Contrary to `FutureObj`, `LocalFutureObj` does not have a `Send` bound.
+pub struct LocalFutureObj<T> {
+ ptr: *mut (),
+ poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
+ drop_fn: unsafe fn(*mut ()),
+ _marker: PhantomData<T>,
+}
+
+impl<T> LocalFutureObj<T> {
+ /// Create a `LocalFutureObj` from a custom trait object representation.
+ #[inline]
+ pub fn new<F: UnsafeFutureObj<T>>(f: F) -> LocalFutureObj<T> {
+ LocalFutureObj {
+ ptr: f.into_raw(),
+ poll_fn: F::poll,
+ drop_fn: F::drop,
+ _marker: PhantomData,
+ }
+ }
+
+ /// Converts the `LocalFutureObj` into a `FutureObj`
+ /// To make this operation safe one has to ensure that the `UnsafeFutureObj`
+ /// instance from which this `LocalFutureObj` was created actually
+ /// implements `Send`.
+ #[inline]
+ pub unsafe fn as_future_obj(self) -> FutureObj<T> {
+ FutureObj(self)
+ }
+}
+
+impl<T> fmt::Debug for LocalFutureObj<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("LocalFutureObj")
+ .finish()
+ }
+}
+
+impl<T> From<FutureObj<T>> for LocalFutureObj<T> {
+ #[inline]
+ fn from(f: FutureObj<T>) -> LocalFutureObj<T> {
+ f.0
+ }
+}
+
+impl<T> Future for LocalFutureObj<T> {
+ type Output = T;
+
+ #[inline]
+ fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
+ unsafe {
+ (self.poll_fn)(self.ptr, cx)
+ }
+ }
+}
+
+impl<T> Drop for LocalFutureObj<T> {
+ fn drop(&mut self) {
+ unsafe {
+ (self.drop_fn)(self.ptr)
+ }
+ }
+}
+
+/// A custom trait object for polling futures, roughly akin to
+/// `Box<dyn Future<Output = T>> + Send`.
+pub struct FutureObj<T>(LocalFutureObj<T>);
+
+unsafe impl<T> Send for FutureObj<T> {}
+
+impl<T> FutureObj<T> {
+ /// Create a `FutureObj` from a custom trait object representation.
+ #[inline]
+ pub fn new<F: UnsafeFutureObj<T> + Send>(f: F) -> FutureObj<T> {
+ FutureObj(LocalFutureObj::new(f))
+ }
+}
+
+impl<T> fmt::Debug for FutureObj<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("FutureObj")
+ .finish()
+ }
+}
+
+impl<T> Future for FutureObj<T> {
+ type Output = T;
+
+ #[inline]
+ fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
+ let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
+ pinned_field.poll(cx)
+ }
+}
+
+/// A custom implementation of a future trait object for `FutureObj`, 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 UnsafeFutureObj<T>: 'static {
+ /// Convert a owned instance into a (conceptually owned) void pointer.
+ fn into_raw(self) -> *mut ();
+
+ /// Poll the future 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(future: *mut (), cx: &mut Context) -> Poll<T>;
+
+ /// Drops the future 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(future: *mut ());
+}
mod poll;
pub use self::poll::Poll;
-mod task;
-pub use self::task::{TaskObj, LocalTaskObj, UnsafeTask};
+mod future_obj;
+pub use self::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj};
mod wake;
pub use self::wake::{Waker, LocalWaker, UnsafeWake};
+++ /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::Future;
-use mem::PinMut;
-use super::{Context, Poll};
-
-/// A custom trait object for polling tasks, roughly akin to
-/// `Box<Future<Output = ()>>`.
-/// Contrary to `TaskObj`, `LocalTaskObj` does not have a `Send` bound.
-pub struct LocalTaskObj {
- ptr: *mut (),
- poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<()>,
- drop_fn: unsafe fn(*mut ()),
-}
-
-impl LocalTaskObj {
- /// Create a `LocalTaskObj` from a custom trait object representation.
- #[inline]
- pub fn new<T: UnsafeTask>(t: T) -> LocalTaskObj {
- LocalTaskObj {
- ptr: t.into_raw(),
- poll_fn: T::poll,
- drop_fn: T::drop,
- }
- }
-
- /// Converts the `LocalTaskObj` into a `TaskObj`
- /// To make this operation safe one has to ensure that the `UnsafeTask`
- /// instance from which this `LocalTaskObj` was created actually implements
- /// `Send`.
- pub unsafe fn as_task_obj(self) -> TaskObj {
- TaskObj(self)
- }
-}
-
-impl fmt::Debug for LocalTaskObj {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("LocalTaskObj")
- .finish()
- }
-}
-
-impl From<TaskObj> for LocalTaskObj {
- fn from(task: TaskObj) -> LocalTaskObj {
- task.0
- }
-}
-
-impl Future for LocalTaskObj {
- type Output = ();
-
- #[inline]
- fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
- unsafe {
- (self.poll_fn)(self.ptr, cx)
- }
- }
-}
-
-impl Drop for LocalTaskObj {
- fn drop(&mut self) {
- unsafe {
- (self.drop_fn)(self.ptr)
- }
- }
-}
-
-/// A custom trait object for polling tasks, roughly akin to
-/// `Box<Future<Output = ()> + Send>`.
-pub struct TaskObj(LocalTaskObj);
-
-unsafe impl Send for TaskObj {}
-
-impl TaskObj {
- /// Create a `TaskObj` from a custom trait object representation.
- #[inline]
- pub fn new<T: UnsafeTask + Send>(t: T) -> TaskObj {
- TaskObj(LocalTaskObj::new(t))
- }
-}
-
-impl fmt::Debug for TaskObj {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("TaskObj")
- .finish()
- }
-}
-
-impl Future for TaskObj {
- type Output = ();
-
- #[inline]
- fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
- let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
- pinned_field.poll(cx)
- }
-}
-
-/// 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 UnsafeTask: '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 ());
-}
};
use std::task::{
Context, Poll, Wake,
- Executor, TaskObj, SpawnObjError,
+ Executor, FutureObj, SpawnObjError,
local_waker_from_nonlocal,
};
struct NoopExecutor;
impl Executor for NoopExecutor {
- fn spawn_obj(&mut self, _: TaskObj) -> Result<(), SpawnObjError> {
+ fn spawn_obj(&mut self, _: FutureObj<T>) -> Result<(), SpawnObjError> {
Ok(())
}
}
use std::task::{
Context, Poll,
Wake, Waker, LocalWaker,
- Executor, TaskObj, SpawnObjError,
+ Executor, FutureObj, SpawnObjError,
local_waker, local_waker_from_nonlocal,
};
struct NoopExecutor;
impl Executor for NoopExecutor {
- fn spawn_obj(&mut self, _: TaskObj) -> Result<(), SpawnObjError> {
+ fn spawn_obj(&mut self, _: FutureObj<()>) -> Result<(), SpawnObjError> {
Ok(())
}
}