about summary refs log tree commit diff
path: root/src/libcore/task
diff options
context:
space:
mode:
authorJosef Reinhard Brandl <mail@josefbrandl.de>2018-06-30 17:26:38 +0200
committerJosef Reinhard Brandl <mail@josefbrandl.de>2018-07-02 13:59:39 +0200
commit3d43f828f5f1261b88f00582074f6cd021f31614 (patch)
treebaff884a7b3e9f15880ac44867bb1016eea7f56f /src/libcore/task
parenta96c88e80fce9d1950aa4700bdeacee35cb9ac02 (diff)
downloadrust-3d43f828f5f1261b88f00582074f6cd021f31614.tar.gz
rust-3d43f828f5f1261b88f00582074f6cd021f31614.zip
Make custom trait object for `Future` generic
Diffstat (limited to 'src/libcore/task')
-rw-r--r--src/libcore/task/executor.rs8
-rw-r--r--src/libcore/task/future_obj.rs (renamed from src/libcore/task/task.rs)99
-rw-r--r--src/libcore/task/mod.rs4
3 files changed, 58 insertions, 53 deletions
diff --git a/src/libcore/task/executor.rs b/src/libcore/task/executor.rs
index 73bf80d2f99..55ea5e724c1 100644
--- a/src/libcore/task/executor.rs
+++ b/src/libcore/task/executor.rs
@@ -13,7 +13,7 @@
             issue = "50547")]
 
 use fmt;
-use super::{TaskObj, LocalTaskObj};
+use super::{FutureObj, LocalFutureObj};
 
 /// A task executor.
 ///
@@ -29,7 +29,7 @@ pub trait 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.
     ///
@@ -76,7 +76,7 @@ pub struct SpawnObjError {
     pub kind: SpawnErrorKind,
 
     /// The task for which spawning was attempted
-    pub task: TaskObj,
+    pub task: FutureObj<()>,
 }
 
 /// The result of a failed spawn
@@ -86,5 +86,5 @@ pub struct SpawnLocalObjError {
     pub kind: SpawnErrorKind,
 
     /// The task for which spawning was attempted
-    pub task: LocalTaskObj,
+    pub task: LocalFutureObj<()>,
 }
diff --git a/src/libcore/task/task.rs b/src/libcore/task/future_obj.rs
index c5a41873db4..3ed3bd51cf6 100644
--- a/src/libcore/task/task.rs
+++ b/src/libcore/task/future_obj.rs
@@ -14,63 +14,68 @@
 
 use fmt;
 use future::Future;
+use marker::PhantomData;
 use mem::PinMut;
-use super::{Context, Poll};
+use task::{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 {
+/// 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<()>,
+    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
     drop_fn: unsafe fn(*mut ()),
+    _marker: PhantomData<T>,
 }
 
-impl LocalTaskObj {
-    /// Create a `LocalTaskObj` from a custom trait object representation.
+impl<T> LocalFutureObj<T> {
+    /// Create a `LocalFutureObj` 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,
+    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 `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)
+    /// 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 fmt::Debug for LocalTaskObj {
+impl<T> fmt::Debug for LocalFutureObj<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("LocalTaskObj")
+        f.debug_struct("LocalFutureObj")
             .finish()
     }
 }
 
-impl From<TaskObj> for LocalTaskObj {
-    fn from(task: TaskObj) -> LocalTaskObj {
-        task.0
+impl<T> From<FutureObj<T>> for LocalFutureObj<T> {
+    #[inline]
+    fn from(f: FutureObj<T>) -> LocalFutureObj<T> {
+        f.0
     }
 }
 
-impl Future for LocalTaskObj {
-    type Output = ();
+impl<T> Future for LocalFutureObj<T> {
+    type Output = T;
 
     #[inline]
-    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
         unsafe {
             (self.poll_fn)(self.ptr, cx)
         }
     }
 }
 
-impl Drop for LocalTaskObj {
+impl<T> Drop for LocalFutureObj<T> {
     fn drop(&mut self) {
         unsafe {
             (self.drop_fn)(self.ptr)
@@ -78,38 +83,38 @@ impl Drop for LocalTaskObj {
     }
 }
 
-/// A custom trait object for polling tasks, roughly akin to
-/// `Box<Future<Output = ()> + Send>`.
-pub struct TaskObj(LocalTaskObj);
+/// A custom trait object for polling futures, roughly akin to
+/// `Box<dyn Future<Output = T>> + Send`.
+pub struct FutureObj<T>(LocalFutureObj<T>);
 
-unsafe impl Send for TaskObj {}
+unsafe impl<T> Send for FutureObj<T> {}
 
-impl TaskObj {
-    /// Create a `TaskObj` from a custom trait object representation.
+impl<T> FutureObj<T> {
+    /// Create a `FutureObj` from a custom trait object representation.
     #[inline]
-    pub fn new<T: UnsafeTask + Send>(t: T) -> TaskObj {
-        TaskObj(LocalTaskObj::new(t))
+    pub fn new<F: UnsafeFutureObj<T> + Send>(f: F) -> FutureObj<T> {
+        FutureObj(LocalFutureObj::new(f))
     }
 }
 
-impl fmt::Debug for TaskObj {
+impl<T> fmt::Debug for FutureObj<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("TaskObj")
+        f.debug_struct("FutureObj")
             .finish()
     }
 }
 
-impl Future for TaskObj {
-    type Output = ();
+impl<T> Future for FutureObj<T> {
+    type Output = T;
 
     #[inline]
-    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
+    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 task trait object for `TaskObj`, providing
+/// 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,
@@ -118,25 +123,25 @@ impl Future for TaskObj {
 /// 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 {
+pub unsafe trait UnsafeFutureObj<T>: '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.
+    /// 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(task: *mut (), cx: &mut Context) -> Poll<()>;
+    unsafe fn poll(future: *mut (), cx: &mut Context) -> Poll<T>;
 
-    /// Drops the task represented by the given void pointer.
+    /// 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(task: *mut ());
+    unsafe fn drop(future: *mut ());
 }
diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs
index d167a374105..06cd7a9dd77 100644
--- a/src/libcore/task/mod.rs
+++ b/src/libcore/task/mod.rs
@@ -25,8 +25,8 @@ pub use self::executor::{
 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};