From c055fef0104f017b9f6aaa25ba0fc69ccb34ae8e Mon Sep 17 00:00:00 2001 From: Josef Reinhard Brandl Date: Tue, 26 Jun 2018 21:06:20 +0200 Subject: [PATCH] Nested `LocalTaskObj` in `TaskObj`, remove `SpawnErrorObj` conversions --- src/libcore/task/spawn_error.rs | 20 -------- src/libcore/task/task.rs | 89 +++++++++++++-------------------- 2 files changed, 34 insertions(+), 75 deletions(-) diff --git a/src/libcore/task/spawn_error.rs b/src/libcore/task/spawn_error.rs index 57bb9ebeb30d..42d37efbe197 100644 --- a/src/libcore/task/spawn_error.rs +++ b/src/libcore/task/spawn_error.rs @@ -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::(self) - } -} - -impl From for SpawnLocalObjError { - fn from(error: SpawnObjError) -> SpawnLocalObjError { - unsafe { - // Safety: Both structs have the same memory layout - mem::transmute::(error) - } - } -} diff --git a/src/libcore/task/task.rs b/src/libcore/task/task.rs index 9896d7f5ff22..c5a41873db42 100644 --- a/src/libcore/task/task.rs +++ b/src/libcore/task/task.rs @@ -14,57 +14,9 @@ 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 + 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: 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, 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>`. /// Contrary to `TaskObj`, `LocalTaskObj` does not have a `Send` bound. @@ -90,8 +42,7 @@ impl 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::(self) + TaskObj(self) } } @@ -104,10 +55,7 @@ impl fmt::Debug for LocalTaskObj { impl From for LocalTaskObj { fn from(task: TaskObj) -> LocalTaskObj { - unsafe { - // Safety: Both structs have the same memory layout - mem::transmute::(task) - } + task.0 } } @@ -130,6 +78,37 @@ impl Drop for LocalTaskObj { } } +/// A custom trait object for polling tasks, roughly akin to +/// `Box + 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: 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, 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. ///