Nested LocalTaskObj
in TaskObj
, remove SpawnErrorObj
conversions
This commit is contained in:
parent
433e6b31a7
commit
c055fef010
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<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 @@ 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::<LocalTaskObj, TaskObj>(self)
|
||||
TaskObj(self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,10 +55,7 @@ impl fmt::Debug for LocalTaskObj {
|
||||
|
||||
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 @@ impl Drop for LocalTaskObj {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user