/// 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)
- }
- }
-}
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.
/// 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)
}
}
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
}
}
}
}
+/// 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.
///