25
25
26
26
#[ allow( missing_doc) ] ;
27
27
28
+
29
+ use std:: cast;
28
30
use std:: cell:: Cell ;
29
31
use std:: comm:: { PortOne , oneshot} ;
30
32
use std:: task;
31
33
use std:: util:: replace;
32
34
33
- /// A type encapsulating the result of a computation which may not be complete
35
+ # [ doc = "The future type" ]
34
36
pub struct Future < A > {
35
37
priv state : FutureState < A > ,
36
38
}
37
39
40
+ // n.b. It should be possible to get rid of this.
41
+ // Add a test, though -- tjc
42
+ // FIXME(#2829) -- futures should not be copyable, because they close
43
+ // over ~fn's that have pipes and so forth within!
44
+ #[ unsafe_destructor]
45
+ impl < A > Drop for Future < A > {
46
+ fn drop ( & mut self ) { }
47
+ }
48
+
38
49
enum FutureState < A > {
39
50
Pending ( ~fn ( ) -> A ) ,
40
51
Evaluating ,
@@ -60,171 +71,156 @@ impl<A> Future<A> {
60
71
_ => fail ! ( "Logic error." ) ,
61
72
}
62
73
}
74
+ }
63
75
76
+ impl < A > Future < A > {
64
77
pub fn get_ref < ' a > ( & ' a mut self ) -> & ' a A {
65
78
/*!
66
79
* Executes the future's closure and then returns a borrowed
67
80
* pointer to the result. The borrowed pointer lasts as long as
68
81
* the future.
69
82
*/
70
- match self . state {
71
- Forced ( ref v) => return v,
72
- Evaluating => fail ! ( "Recursive forcing of future!" ) ,
73
- Pending ( _) => {
74
- match replace ( & mut self . state , Evaluating ) {
83
+ unsafe {
84
+ {
85
+ match self . state {
86
+ Forced ( ref mut v) => { return cast:: transmute ( v) ; }
87
+ Evaluating => fail ! ( "Recursive forcing of future!" ) ,
88
+ Pending ( _) => { }
89
+ }
90
+ }
91
+ {
92
+ let state = replace ( & mut self . state , Evaluating ) ;
93
+ match state {
75
94
Forced ( _) | Evaluating => fail ! ( "Logic error." ) ,
76
95
Pending ( f) => {
77
96
self . state = Forced ( f ( ) ) ;
78
- self . get_ref ( )
97
+ cast :: transmute ( self . get_ref ( ) )
79
98
}
80
99
}
81
100
}
82
101
}
83
102
}
103
+ }
84
104
85
- pub fn from_value ( val : A ) -> Future < A > {
86
- /*!
87
- * Create a future from a value.
88
- *
89
- * The value is immediately available and calling `get` later will
90
- * not block.
91
- */
105
+ pub fn from_value < A > ( val : A ) -> Future < A > {
106
+ /*!
107
+ * Create a future from a value.
108
+ *
109
+ * The value is immediately available and calling `get` later will
110
+ * not block.
111
+ */
92
112
93
- Future { state : Forced ( val) }
94
- }
113
+ Future { state : Forced ( val) }
114
+ }
95
115
96
- pub fn from_fn ( f : ~fn ( ) -> A ) -> Future < A > {
97
- /*!
98
- * Create a future from a function.
99
- *
100
- * The first time that the value is requested it will be retrieved by
101
- * calling the function. Note that this function is a local
102
- * function. It is not spawned into another task.
103
- */
104
-
105
- Future { state : Pending ( f) }
116
+ pub fn from_port < A : Send > ( port : PortOne < A > ) -> Future < A > {
117
+ /*!
118
+ * Create a future from a port
119
+ *
120
+ * The first time that the value is requested the task will block
121
+ * waiting for the result to be received on the port.
122
+ */
123
+
124
+ let port = Cell :: new ( port) ;
125
+ do from_fn {
126
+ port. take ( ) . recv ( )
106
127
}
107
128
}
108
129
109
- impl < A : Send > Future < A > {
110
- pub fn from_port ( port : PortOne < A > ) -> Future < A > {
111
- /*!
112
- * Create a future from a port
113
- *
114
- * The first time that the value is requested the task will block
115
- * waiting for the result to be received on the port.
116
- */
117
-
118
- let port = Cell :: new ( port) ;
119
- do Future :: from_fn {
120
- port. take ( ) . recv ( )
121
- }
122
- }
130
+ pub fn from_fn < A > ( f : ~fn ( ) -> A ) -> Future < A > {
131
+ /*!
132
+ * Create a future from a function.
133
+ *
134
+ * The first time that the value is requested it will be retrieved by
135
+ * calling the function. Note that this function is a local
136
+ * function. It is not spawned into another task.
137
+ */
123
138
124
- pub fn spawn( blk : ~fn ( ) -> A ) -> Future < A > {
125
- /*!
126
- * Create a future from a unique closure.
127
- *
128
- * The closure will be run in a new task and its result used as the
129
- * value of the future.
130
- */
139
+ Future { state : Pending ( f) }
140
+ }
131
141
132
- let ( port, chan) = oneshot ( ) ;
142
+ pub fn spawn < A : Send > ( blk : ~fn ( ) -> A ) -> Future < A > {
143
+ /*!
144
+ * Create a future from a unique closure.
145
+ *
146
+ * The closure will be run in a new task and its result used as the
147
+ * value of the future.
148
+ */
133
149
134
- do task:: spawn_with ( chan) |chan| {
135
- chan. send ( blk ( ) ) ;
136
- }
150
+ let ( port, chan) = oneshot ( ) ;
137
151
138
- Future :: from_port ( port)
152
+ let chan = Cell :: new ( chan) ;
153
+ do task:: spawn {
154
+ let chan = chan. take ( ) ;
155
+ chan. send ( blk ( ) ) ;
139
156
}
140
157
141
- pub fn spawn_with < B : Send > ( v : B , blk : ~fn ( B ) -> A ) -> Future < A > {
142
- /*!
143
- * Create a future from a unique closure taking one argument.
144
- *
145
- * The closure and its argument will be moved into a new task. The
146
- * closure will be run and its result used as the value of the future.
147
- */
148
-
149
- let ( port, chan) = oneshot ( ) ;
150
-
151
- do task:: spawn_with ( ( v, chan) ) |( v, chan) | {
152
- chan. send ( blk ( v) ) ;
153
- }
154
-
155
- Future :: from_port ( port)
156
- }
158
+ return from_port ( port) ;
157
159
}
158
160
159
161
#[ cfg( test) ]
160
162
mod test {
161
- use future:: Future ;
163
+ use future:: * ;
162
164
163
165
use std:: cell:: Cell ;
164
166
use std:: comm:: oneshot;
165
167
use std:: task;
166
168
167
169
#[ test]
168
170
fn test_from_value ( ) {
169
- let mut f = Future :: from_value ( ~"snail") ;
171
+ let mut f = from_value ( ~"snail") ;
170
172
assert_eq ! ( f. get( ) , ~"snail");
171
173
}
172
174
173
175
#[test]
174
176
fn test_from_port() {
175
177
let (po, ch) = oneshot();
176
178
ch.send(~" whale");
177
- let mut f = Future:: from_port(po);
179
+ let mut f = from_port(po);
178
180
assert_eq!(f.get(), ~" whale");
179
181
}
180
182
181
183
#[test]
182
184
fn test_from_fn() {
183
- let mut f = Future:: from_fn(|| ~" brail");
185
+ let mut f = from_fn(|| ~" brail");
184
186
assert_eq!(f.get(), ~" brail");
185
187
}
186
188
187
189
#[test]
188
190
fn test_interface_get() {
189
- let mut f = Future:: from_value(~" fail");
191
+ let mut f = from_value(~" fail");
190
192
assert_eq!(f.get(), ~" fail");
191
193
}
192
194
193
195
#[test]
194
196
fn test_interface_unwrap() {
195
- let f = Future:: from_value(~" fail");
197
+ let f = from_value(~" fail");
196
198
assert_eq!(f.unwrap(), ~" fail");
197
199
}
198
200
199
201
#[test]
200
202
fn test_get_ref_method() {
201
- let mut f = Future:: from_value(22);
203
+ let mut f = from_value(22);
202
204
assert_eq!(*f.get_ref(), 22);
203
205
}
204
206
205
207
#[test]
206
208
fn test_spawn() {
207
- let mut f = Future:: spawn(|| ~" bale");
209
+ let mut f = spawn(|| ~" bale");
208
210
assert_eq!(f.get(), ~" bale");
209
211
}
210
212
211
- #[test]
212
- fn test_spawn_with() {
213
- let mut f = Future::spawn_with(~" gale", |s| { s });
214
- assert_eq!(f.get(), ~" gale");
215
- }
216
-
217
213
#[test]
218
214
#[should_fail]
219
215
fn test_futurefail() {
220
- let mut f = Future:: spawn(|| fail!());
216
+ let mut f = spawn(|| fail!());
221
217
let _x: ~str = f.get();
222
218
}
223
219
224
220
#[test]
225
221
fn test_sendable_future() {
226
222
let expected = " schlorf" ;
227
- let f = Cell :: new( do Future :: spawn { expected } ) ;
223
+ let f = Cell :: new( do spawn { expected } ) ;
228
224
do task:: spawn {
229
225
let mut f = f. take( ) ;
230
226
let actual = f. get( ) ;
0 commit comments