14
14
15
15
use fmt;
16
16
use future:: Future ;
17
- use mem:: { self , PinMut } ;
17
+ use mem:: PinMut ;
18
18
use super :: { Context , Poll } ;
19
19
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
-
68
20
/// A custom trait object for polling tasks, roughly akin to
69
21
/// `Box<Future<Output = ()>>`.
70
22
/// Contrary to `TaskObj`, `LocalTaskObj` does not have a `Send` bound.
@@ -90,8 +42,7 @@ impl LocalTaskObj {
90
42
/// instance from which this `LocalTaskObj` was created actually implements
91
43
/// `Send`.
92
44
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 )
95
46
}
96
47
}
97
48
@@ -104,10 +55,7 @@ impl fmt::Debug for LocalTaskObj {
104
55
105
56
impl From < TaskObj > for LocalTaskObj {
106
57
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
111
59
}
112
60
}
113
61
@@ -130,6 +78,37 @@ impl Drop for LocalTaskObj {
130
78
}
131
79
}
132
80
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
+
133
112
/// A custom implementation of a task trait object for `TaskObj`, providing
134
113
/// a hand-rolled vtable.
135
114
///
0 commit comments