25
25
26
26
#[ allow( missing_doc) ] ;
27
27
28
-
29
- use std:: cast;
30
28
use std:: cell:: Cell ;
31
29
use std:: comm:: { PortOne , oneshot} ;
32
30
use std:: task;
33
31
use std:: util:: replace;
34
32
35
- # [ doc = "The future type" ]
33
+ /// A type encapsulating the result of a computation which may not be complete
36
34
pub struct Future < A > {
37
35
priv state : FutureState < A > ,
38
36
}
39
37
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
-
49
38
enum FutureState < A > {
50
39
Pending ( ~fn ( ) -> A ) ,
51
40
Evaluating ,
@@ -71,156 +60,171 @@ impl<A> Future<A> {
71
60
_ => fail ! ( "Logic error." ) ,
72
61
}
73
62
}
74
- }
75
63
76
- impl < A > Future < A > {
77
64
pub fn get_ref < ' a > ( & ' a mut self ) -> & ' a A {
78
65
/*!
79
66
* Executes the future's closure and then returns a borrowed
80
67
* pointer to the result. The borrowed pointer lasts as long as
81
68
* the future.
82
69
*/
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 {
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 ) {
94
75
Forced ( _) | Evaluating => fail ! ( "Logic error." ) ,
95
76
Pending ( f) => {
96
77
self . state = Forced ( f ( ) ) ;
97
- cast :: transmute ( self . get_ref ( ) )
78
+ self . get_ref ( )
98
79
}
99
80
}
100
81
}
101
82
}
102
83
}
103
- }
104
-
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
- */
112
84
113
- Future { state : Forced ( val) }
114
- }
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
+ */
115
92
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
- */
93
+ Future { state : Forced ( val) }
94
+ }
123
95
124
- let port = Cell :: new ( port) ;
125
- do from_fn {
126
- port. take ( ) . recv ( )
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) }
127
106
}
128
107
}
129
108
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
- */
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
+ }
138
123
139
- Future { state : Pending ( f) }
140
- }
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
+ */
141
131
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
- */
132
+ let ( port, chan) = oneshot ( ) ;
149
133
150
- let ( port, chan) = oneshot ( ) ;
134
+ do task:: spawn_with ( chan) |chan| {
135
+ chan. send ( blk ( ) ) ;
136
+ }
151
137
152
- let chan = Cell :: new ( chan) ;
153
- do task:: spawn {
154
- let chan = chan. take ( ) ;
155
- chan. send ( blk ( ) ) ;
138
+ Future :: from_port ( port)
156
139
}
157
140
158
- return from_port ( port) ;
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
+ }
159
157
}
160
158
161
159
#[ cfg( test) ]
162
160
mod test {
163
- use future:: * ;
161
+ use future:: Future ;
164
162
165
163
use std:: cell:: Cell ;
166
164
use std:: comm:: oneshot;
167
165
use std:: task;
168
166
169
167
#[ test]
170
168
fn test_from_value ( ) {
171
- let mut f = from_value ( ~"snail") ;
169
+ let mut f = Future :: from_value ( ~"snail") ;
172
170
assert_eq ! ( f. get( ) , ~"snail");
173
171
}
174
172
175
173
#[test]
176
174
fn test_from_port() {
177
175
let (po, ch) = oneshot();
178
176
ch.send(~" whale");
179
- let mut f = from_port(po);
177
+ let mut f = Future:: from_port(po);
180
178
assert_eq!(f.get(), ~" whale");
181
179
}
182
180
183
181
#[test]
184
182
fn test_from_fn() {
185
- let mut f = from_fn(|| ~" brail");
183
+ let mut f = Future:: from_fn(|| ~" brail");
186
184
assert_eq!(f.get(), ~" brail");
187
185
}
188
186
189
187
#[test]
190
188
fn test_interface_get() {
191
- let mut f = from_value(~" fail");
189
+ let mut f = Future:: from_value(~" fail");
192
190
assert_eq!(f.get(), ~" fail");
193
191
}
194
192
195
193
#[test]
196
194
fn test_interface_unwrap() {
197
- let f = from_value(~" fail");
195
+ let f = Future:: from_value(~" fail");
198
196
assert_eq!(f.unwrap(), ~" fail");
199
197
}
200
198
201
199
#[test]
202
200
fn test_get_ref_method() {
203
- let mut f = from_value(22);
201
+ let mut f = Future:: from_value(22);
204
202
assert_eq!(*f.get_ref(), 22);
205
203
}
206
204
207
205
#[test]
208
206
fn test_spawn() {
209
- let mut f = spawn(|| ~" bale");
207
+ let mut f = Future:: spawn(|| ~" bale");
210
208
assert_eq!(f.get(), ~" bale");
211
209
}
212
210
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
+
213
217
#[test]
214
218
#[should_fail]
215
219
fn test_futurefail() {
216
- let mut f = spawn(|| fail!());
220
+ let mut f = Future:: spawn(|| fail!());
217
221
let _x: ~str = f.get();
218
222
}
219
223
220
224
#[test]
221
225
fn test_sendable_future() {
222
226
let expected = " schlorf" ;
223
- let f = Cell :: new( do spawn { expected } ) ;
227
+ let f = Cell :: new( do Future :: spawn { expected } ) ;
224
228
do task:: spawn {
225
229
let mut f = f. take( ) ;
226
230
let actual = f. get( ) ;
0 commit comments