1414
1515use fmt;
1616use future:: Future ;
17- use mem:: { self , PinMut } ;
17+ use mem:: PinMut ;
1818use super :: { Context , Poll } ;
1919
20- /// A custom trait object for polling tasks, roughly akin to
21- /// `Box<Future<Output = ()> + Send>`.
22- pub struct TaskObj {
23- ptr : * mut ( ) ,
24- poll_fn : unsafe fn ( * mut ( ) , & mut Context ) -> Poll < ( ) > ,
25- drop_fn : unsafe fn ( * mut ( ) ) ,
26- }
27-
28- unsafe impl Send for TaskObj { }
29-
30- impl TaskObj {
31- /// Create a `TaskObj` from a custom trait object representation.
32- #[ inline]
33- pub fn new < T : UnsafeTask + Send > ( t : T ) -> TaskObj {
34- TaskObj {
35- ptr : t. into_raw ( ) ,
36- poll_fn : T :: poll,
37- drop_fn : T :: drop,
38- }
39- }
40- }
41-
42- impl fmt:: Debug for TaskObj {
43- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
44- f. debug_struct ( "TaskObj" )
45- . finish ( )
46- }
47- }
48-
49- impl Future for TaskObj {
50- type Output = ( ) ;
51-
52- #[ inline]
53- fn poll ( self : PinMut < Self > , cx : & mut Context ) -> Poll < ( ) > {
54- unsafe {
55- ( self . poll_fn ) ( self . ptr , cx)
56- }
57- }
58- }
59-
60- impl Drop for TaskObj {
61- fn drop ( & mut self ) {
62- unsafe {
63- ( self . drop_fn ) ( self . ptr )
64- }
65- }
66- }
67-
6820/// A custom trait object for polling tasks, roughly akin to
6921/// `Box<Future<Output = ()>>`.
7022/// Contrary to `TaskObj`, `LocalTaskObj` does not have a `Send` bound.
@@ -90,8 +42,7 @@ impl LocalTaskObj {
9042 /// instance from which this `LocalTaskObj` was created actually implements
9143 /// `Send`.
9244 pub unsafe fn as_task_obj ( self ) -> TaskObj {
93- // Safety: Both structs have the same memory layout
94- mem:: transmute :: < LocalTaskObj , TaskObj > ( self )
45+ TaskObj ( self )
9546 }
9647}
9748
@@ -104,10 +55,7 @@ impl fmt::Debug for LocalTaskObj {
10455
10556impl From < TaskObj > for LocalTaskObj {
10657 fn from ( task : TaskObj ) -> LocalTaskObj {
107- unsafe {
108- // Safety: Both structs have the same memory layout
109- mem:: transmute :: < TaskObj , LocalTaskObj > ( task)
110- }
58+ task. 0
11159 }
11260}
11361
@@ -130,6 +78,37 @@ impl Drop for LocalTaskObj {
13078 }
13179}
13280
81+ /// A custom trait object for polling tasks, roughly akin to
82+ /// `Box<Future<Output = ()> + Send>`.
83+ pub struct TaskObj ( LocalTaskObj ) ;
84+
85+ unsafe impl Send for TaskObj { }
86+
87+ impl TaskObj {
88+ /// Create a `TaskObj` from a custom trait object representation.
89+ #[ inline]
90+ pub fn new < T : UnsafeTask + Send > ( t : T ) -> TaskObj {
91+ TaskObj ( LocalTaskObj :: new ( t) )
92+ }
93+ }
94+
95+ impl fmt:: Debug for TaskObj {
96+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
97+ f. debug_struct ( "TaskObj" )
98+ . finish ( )
99+ }
100+ }
101+
102+ impl Future for TaskObj {
103+ type Output = ( ) ;
104+
105+ #[ inline]
106+ fn poll ( self : PinMut < Self > , cx : & mut Context ) -> Poll < ( ) > {
107+ let pinned_field = unsafe { PinMut :: map_unchecked ( self , |x| & mut x. 0 ) } ;
108+ pinned_field. poll ( cx)
109+ }
110+ }
111+
133112/// A custom implementation of a task trait object for `TaskObj`, providing
134113/// a hand-rolled vtable.
135114///
0 commit comments