14
14
15
15
use fmt;
16
16
use future:: Future ;
17
+ use marker:: PhantomData ;
17
18
use mem:: PinMut ;
18
- use super :: { Context , Poll } ;
19
+ use task :: { Context , Poll } ;
19
20
20
- /// A custom trait object for polling tasks , roughly akin to
21
- /// `Box<Future<Output = () >>`.
22
- /// Contrary to `TaskObj `, `LocalTaskObj ` does not have a `Send` bound.
23
- pub struct LocalTaskObj {
21
+ /// A custom trait object for polling futures , roughly akin to
22
+ /// `Box<dyn Future<Output = T >>`.
23
+ /// Contrary to `FutureObj `, `LocalFutureObj ` does not have a `Send` bound.
24
+ pub struct LocalFutureObj < T > {
24
25
ptr : * mut ( ) ,
25
- poll_fn : unsafe fn ( * mut ( ) , & mut Context ) -> Poll < ( ) > ,
26
+ poll_fn : unsafe fn ( * mut ( ) , & mut Context ) -> Poll < T > ,
26
27
drop_fn : unsafe fn ( * mut ( ) ) ,
28
+ _marker : PhantomData < T > ,
27
29
}
28
30
29
- impl LocalTaskObj {
30
- /// Create a `LocalTaskObj ` from a custom trait object representation.
31
+ impl < T > LocalFutureObj < T > {
32
+ /// Create a `LocalFutureObj ` from a custom trait object representation.
31
33
#[ inline]
32
- pub fn new < T : UnsafeTask > ( t : T ) -> LocalTaskObj {
33
- LocalTaskObj {
34
- ptr : t. into_raw ( ) ,
35
- poll_fn : T :: poll,
36
- drop_fn : T :: drop,
34
+ pub fn new < F : UnsafeFutureObj < T > > ( f : F ) -> LocalFutureObj < T > {
35
+ LocalFutureObj {
36
+ ptr : f. into_raw ( ) ,
37
+ poll_fn : F :: poll,
38
+ drop_fn : F :: drop,
39
+ _marker : PhantomData ,
37
40
}
38
41
}
39
42
40
- /// Converts the `LocalTaskObj` into a `TaskObj`
41
- /// To make this operation safe one has to ensure that the `UnsafeTask`
42
- /// instance from which this `LocalTaskObj` was created actually implements
43
- /// `Send`.
44
- pub unsafe fn as_task_obj ( self ) -> TaskObj {
45
- TaskObj ( self )
43
+ /// Converts the `LocalFutureObj` into a `FutureObj`
44
+ /// To make this operation safe one has to ensure that the `UnsafeFutureObj`
45
+ /// instance from which this `LocalFutureObj` was created actually
46
+ /// implements `Send`.
47
+ #[ inline]
48
+ pub unsafe fn as_future_obj ( self ) -> FutureObj < T > {
49
+ FutureObj ( self )
46
50
}
47
51
}
48
52
49
- impl fmt:: Debug for LocalTaskObj {
53
+ impl < T > fmt:: Debug for LocalFutureObj < T > {
50
54
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
51
- f. debug_struct ( "LocalTaskObj " )
55
+ f. debug_struct ( "LocalFutureObj " )
52
56
. finish ( )
53
57
}
54
58
}
55
59
56
- impl From < TaskObj > for LocalTaskObj {
57
- fn from ( task : TaskObj ) -> LocalTaskObj {
58
- task. 0
60
+ impl < T > From < FutureObj < T > > for LocalFutureObj < T > {
61
+ #[ inline]
62
+ fn from ( f : FutureObj < T > ) -> LocalFutureObj < T > {
63
+ f. 0
59
64
}
60
65
}
61
66
62
- impl Future for LocalTaskObj {
63
- type Output = ( ) ;
67
+ impl < T > Future for LocalFutureObj < T > {
68
+ type Output = T ;
64
69
65
70
#[ inline]
66
- fn poll ( self : PinMut < Self > , cx : & mut Context ) -> Poll < ( ) > {
71
+ fn poll ( self : PinMut < Self > , cx : & mut Context ) -> Poll < T > {
67
72
unsafe {
68
73
( self . poll_fn ) ( self . ptr , cx)
69
74
}
70
75
}
71
76
}
72
77
73
- impl Drop for LocalTaskObj {
78
+ impl < T > Drop for LocalFutureObj < T > {
74
79
fn drop ( & mut self ) {
75
80
unsafe {
76
81
( self . drop_fn ) ( self . ptr )
77
82
}
78
83
}
79
84
}
80
85
81
- /// A custom trait object for polling tasks , roughly akin to
82
- /// `Box<Future<Output = ()> + Send> `.
83
- pub struct TaskObj ( LocalTaskObj ) ;
86
+ /// A custom trait object for polling futures , roughly akin to
87
+ /// `Box<dyn Future<Output = T>> + Send`.
88
+ pub struct FutureObj < T > ( LocalFutureObj < T > ) ;
84
89
85
- unsafe impl Send for TaskObj { }
90
+ unsafe impl < T > Send for FutureObj < T > { }
86
91
87
- impl TaskObj {
88
- /// Create a `TaskObj ` from a custom trait object representation.
92
+ impl < T > FutureObj < T > {
93
+ /// Create a `FutureObj ` from a custom trait object representation.
89
94
#[ inline]
90
- pub fn new < T : UnsafeTask + Send > ( t : T ) -> TaskObj {
91
- TaskObj ( LocalTaskObj :: new ( t ) )
95
+ pub fn new < F : UnsafeFutureObj < T > + Send > ( f : F ) -> FutureObj < T > {
96
+ FutureObj ( LocalFutureObj :: new ( f ) )
92
97
}
93
98
}
94
99
95
- impl fmt:: Debug for TaskObj {
100
+ impl < T > fmt:: Debug for FutureObj < T > {
96
101
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
97
- f. debug_struct ( "TaskObj " )
102
+ f. debug_struct ( "FutureObj " )
98
103
. finish ( )
99
104
}
100
105
}
101
106
102
- impl Future for TaskObj {
103
- type Output = ( ) ;
107
+ impl < T > Future for FutureObj < T > {
108
+ type Output = T ;
104
109
105
110
#[ inline]
106
- fn poll ( self : PinMut < Self > , cx : & mut Context ) -> Poll < ( ) > {
111
+ fn poll ( self : PinMut < Self > , cx : & mut Context ) -> Poll < T > {
107
112
let pinned_field = unsafe { PinMut :: map_unchecked ( self , |x| & mut x. 0 ) } ;
108
113
pinned_field. poll ( cx)
109
114
}
110
115
}
111
116
112
- /// A custom implementation of a task trait object for `TaskObj `, providing
117
+ /// A custom implementation of a future trait object for `FutureObj `, providing
113
118
/// a hand-rolled vtable.
114
119
///
115
120
/// This custom representation is typically used only in `no_std` contexts,
@@ -118,25 +123,25 @@ impl Future for TaskObj {
118
123
/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
119
124
/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
120
125
/// called.
121
- pub unsafe trait UnsafeTask : ' static {
126
+ pub unsafe trait UnsafeFutureObj < T > : ' static {
122
127
/// Convert a owned instance into a (conceptually owned) void pointer.
123
128
fn into_raw ( self ) -> * mut ( ) ;
124
129
125
- /// Poll the task represented by the given void pointer.
130
+ /// Poll the future represented by the given void pointer.
126
131
///
127
132
/// # Safety
128
133
///
129
134
/// The trait implementor must guarantee that it is safe to repeatedly call
130
135
/// `poll` with the result of `into_raw` until `drop` is called; such calls
131
136
/// are not, however, allowed to race with each other or with calls to `drop`.
132
- unsafe fn poll ( task : * mut ( ) , cx : & mut Context ) -> Poll < ( ) > ;
137
+ unsafe fn poll ( future : * mut ( ) , cx : & mut Context ) -> Poll < T > ;
133
138
134
- /// Drops the task represented by the given void pointer.
139
+ /// Drops the future represented by the given void pointer.
135
140
///
136
141
/// # Safety
137
142
///
138
143
/// The trait implementor must guarantee that it is safe to call this
139
144
/// function once per `into_raw` invocation; that call cannot race with
140
145
/// other calls to `drop` or `poll`.
141
- unsafe fn drop ( task : * mut ( ) ) ;
146
+ unsafe fn drop ( future : * mut ( ) ) ;
142
147
}
0 commit comments