]> git.lizzy.rs Git - rust.git/commitdiff
Nested `LocalTaskObj` in `TaskObj`, remove `SpawnErrorObj` conversions
authorJosef Reinhard Brandl <mail@josefbrandl.de>
Tue, 26 Jun 2018 19:06:20 +0000 (21:06 +0200)
committerJosef Reinhard Brandl <mail@josefbrandl.de>
Tue, 26 Jun 2018 19:06:20 +0000 (21:06 +0200)
src/libcore/task/spawn_error.rs
src/libcore/task/task.rs

index 57bb9ebeb30d974814c042062be9d9f43a7defdf..42d37efbe1977e63149f473958569682fb164efe 100644 (file)
@@ -60,23 +60,3 @@ pub struct SpawnLocalObjError {
     /// The task for which spawning was attempted
     pub task: LocalTaskObj,
 }
-
-impl SpawnLocalObjError {
-    /// Converts the `SpawnLocalObjError` into a `SpawnObjError`
-    /// To make this operation safe one has to ensure that the `UnsafeTask`
-    /// instance from which the `LocalTaskObj` stored inside was created
-    /// actually implements `Send`.
-    pub unsafe fn as_spawn_obj_error(self) -> SpawnObjError {
-        // Safety: Both structs have the same memory layout
-        mem::transmute::<SpawnLocalObjError, SpawnObjError>(self)
-    }
-}
-
-impl From<SpawnObjError> for SpawnLocalObjError {
-    fn from(error: SpawnObjError) -> SpawnLocalObjError {
-        unsafe {
-            // Safety: Both structs have the same memory layout
-            mem::transmute::<SpawnObjError, SpawnLocalObjError>(error)
-        }
-    }
-}
index 9896d7f5ff2217e8bd8b5661dad6fd4685ed03d1..c5a41873db42725fbaccfa588996cf0a4ebab68d 100644 (file)
 
 use fmt;
 use future::Future;
-use mem::{self, PinMut};
+use mem::PinMut;
 use super::{Context, Poll};
 
-/// A custom trait object for polling tasks, roughly akin to
-/// `Box<Future<Output = ()> + Send>`.
-pub struct TaskObj {
-    ptr: *mut (),
-    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<()>,
-    drop_fn: unsafe fn(*mut ()),
-}
-
-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 {
-            ptr: t.into_raw(),
-            poll_fn: T::poll,
-            drop_fn: T::drop,
-        }
-    }
-}
-
-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<()> {
-        unsafe {
-            (self.poll_fn)(self.ptr, cx)
-        }
-    }
-}
-
-impl Drop for TaskObj {
-    fn drop(&mut self) {
-        unsafe {
-            (self.drop_fn)(self.ptr)
-        }
-    }
-}
-
 /// A custom trait object for polling tasks, roughly akin to
 /// `Box<Future<Output = ()>>`.
 /// Contrary to `TaskObj`, `LocalTaskObj` does not have a `Send` bound.
@@ -90,8 +42,7 @@ pub fn new<T: UnsafeTask>(t: T) -> LocalTaskObj {
     /// instance from which this `LocalTaskObj` was created actually implements
     /// `Send`.
     pub unsafe fn as_task_obj(self) -> TaskObj {
-        // Safety: Both structs have the same memory layout
-        mem::transmute::<LocalTaskObj, TaskObj>(self)
+        TaskObj(self)
     }
 }
 
@@ -104,10 +55,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl From<TaskObj> for LocalTaskObj {
     fn from(task: TaskObj) -> LocalTaskObj {
-        unsafe {
-            // Safety: Both structs have the same memory layout
-            mem::transmute::<TaskObj, LocalTaskObj>(task)
-        }
+        task.0
     }
 }
 
@@ -130,6 +78,37 @@ fn drop(&mut self) {
     }
 }
 
+/// 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.
 ///