Skip to content

Commit 407d179

Browse files
committed
auto merge of #9285 : sfackler/rust/future, r=alexcrichton
The `Drop` implementation was used to prevent `Future` from being implicitly copyable. Since `~fn`s are no longer copyable, this is no longer needed. I added a cfail test to make sure that this is actually the case. I method-ized all of the `Future` creation methods and added a new one, `spawn_with`, which is similar to `task::spawn_with`. I also got rid of some unused imports in tests.
2 parents 570431f + 963707f commit 407d179

File tree

9 files changed

+115
-95
lines changed

9 files changed

+115
-95
lines changed

doc/tutorial-tasks.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ fn fib(n: uint) -> uint {
280280
12586269025
281281
}
282282
283-
let mut delayed_fib = extra::future::spawn (|| fib(50) );
283+
let mut delayed_fib = extra::future::Future::spawn (|| fib(50) );
284284
make_a_sandwich();
285285
println(fmt!("fib(50) = %?", delayed_fib.get()))
286286
~~~
@@ -304,7 +304,7 @@ fn partial_sum(start: uint) -> f64 {
304304
}
305305
306306
fn main() {
307-
let mut futures = vec::from_fn(1000, |ind| do extra::future::spawn { partial_sum(ind) });
307+
let mut futures = vec::from_fn(1000, |ind| do extra::future::Future::spawn { partial_sum(ind) });
308308
309309
let mut final_res = 0f64;
310310
for ft in futures.mut_iter() {

src/libextra/fileinput.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,6 @@ mod test {
420420
use std::rt::io;
421421
use std::rt::io::Writer;
422422
use std::rt::io::file;
423-
use std::uint;
424423
use std::vec;
425424

426425
fn make_file(path : &Path, contents: &[~str]) {

src/libextra/future.rs

Lines changed: 84 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,16 @@
2525

2626
#[allow(missing_doc)];
2727

28-
29-
use std::cast;
3028
use std::cell::Cell;
3129
use std::comm::{PortOne, oneshot};
3230
use std::task;
3331
use std::util::replace;
3432

35-
#[doc = "The future type"]
33+
/// A type encapsulating the result of a computation which may not be complete
3634
pub struct Future<A> {
3735
priv state: FutureState<A>,
3836
}
3937

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-
4938
enum FutureState<A> {
5039
Pending(~fn() -> A),
5140
Evaluating,
@@ -71,156 +60,171 @@ impl<A> Future<A> {
7160
_ => fail!( "Logic error." ),
7261
}
7362
}
74-
}
7563

76-
impl<A> Future<A> {
7764
pub fn get_ref<'a>(&'a mut self) -> &'a A {
7865
/*!
7966
* Executes the future's closure and then returns a borrowed
8067
* pointer to the result. The borrowed pointer lasts as long as
8168
* the future.
8269
*/
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) {
9475
Forced(_) | Evaluating => fail!("Logic error."),
9576
Pending(f) => {
9677
self.state = Forced(f());
97-
cast::transmute(self.get_ref())
78+
self.get_ref()
9879
}
9980
}
10081
}
10182
}
10283
}
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-
*/
11284

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+
*/
11592

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+
}
12395

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)}
127106
}
128107
}
129108

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+
}
138123

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+
*/
141131

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();
149133

150-
let (port, chan) = oneshot();
134+
do task::spawn_with(chan) |chan| {
135+
chan.send(blk());
136+
}
151137

152-
let chan = Cell::new(chan);
153-
do task::spawn {
154-
let chan = chan.take();
155-
chan.send(blk());
138+
Future::from_port(port)
156139
}
157140

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+
}
159157
}
160158

161159
#[cfg(test)]
162160
mod test {
163-
use future::*;
161+
use future::Future;
164162

165163
use std::cell::Cell;
166164
use std::comm::oneshot;
167165
use std::task;
168166

169167
#[test]
170168
fn test_from_value() {
171-
let mut f = from_value(~"snail");
169+
let mut f = Future::from_value(~"snail");
172170
assert_eq!(f.get(), ~"snail");
173171
}
174172
175173
#[test]
176174
fn test_from_port() {
177175
let (po, ch) = oneshot();
178176
ch.send(~"whale");
179-
let mut f = from_port(po);
177+
let mut f = Future::from_port(po);
180178
assert_eq!(f.get(), ~"whale");
181179
}
182180
183181
#[test]
184182
fn test_from_fn() {
185-
let mut f = from_fn(|| ~"brail");
183+
let mut f = Future::from_fn(|| ~"brail");
186184
assert_eq!(f.get(), ~"brail");
187185
}
188186
189187
#[test]
190188
fn test_interface_get() {
191-
let mut f = from_value(~"fail");
189+
let mut f = Future::from_value(~"fail");
192190
assert_eq!(f.get(), ~"fail");
193191
}
194192
195193
#[test]
196194
fn test_interface_unwrap() {
197-
let f = from_value(~"fail");
195+
let f = Future::from_value(~"fail");
198196
assert_eq!(f.unwrap(), ~"fail");
199197
}
200198
201199
#[test]
202200
fn test_get_ref_method() {
203-
let mut f = from_value(22);
201+
let mut f = Future::from_value(22);
204202
assert_eq!(*f.get_ref(), 22);
205203
}
206204
207205
#[test]
208206
fn test_spawn() {
209-
let mut f = spawn(|| ~"bale");
207+
let mut f = Future::spawn(|| ~"bale");
210208
assert_eq!(f.get(), ~"bale");
211209
}
212210
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+
213217
#[test]
214218
#[should_fail]
215219
fn test_futurefail() {
216-
let mut f = spawn(|| fail!());
220+
let mut f = Future::spawn(|| fail!());
217221
let _x: ~str = f.get();
218222
}
219223
220224
#[test]
221225
fn test_sendable_future() {
222226
let expected = "schlorf";
223-
let f = Cell::new(do spawn { expected });
227+
let f = Cell::new(do Future::spawn { expected });
224228
do task::spawn {
225229
let mut f = f.take();
226230
let actual = f.get();

src/libextra/glob.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,10 +512,8 @@ impl MatchOptions {
512512
513513
#[cfg(test)]
514514
mod test {
515-
use std::{io, os, unstable};
516-
use std::unstable::finally::Finally;
515+
use std::os;
517516
use super::*;
518-
use tempfile;
519517
520518
#[test]
521519
fn test_absolute_pattern() {

src/libextra/par.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::num;
1414
use std::ptr;
1515
use std::sys;
1616
use std::vec;
17-
use future_spawn = future::spawn;
17+
use future::Future;
1818

1919
/**
2020
* The maximum number of tasks this module will spawn for a single
@@ -55,7 +55,7 @@ fn map_slices<A:Clone + Send,B:Clone + Send>(
5555
do xs.as_imm_buf |p, _len| {
5656
let f = f();
5757
let base = base;
58-
let f = do future_spawn() || {
58+
let f = do Future::spawn() || {
5959
unsafe {
6060
let len = end - base;
6161
let slice = (ptr::offset(p, base as int),

src/librustdoc/markdown_writer.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::result;
2020
use std::run;
2121
use std::str;
2222
use std::task;
23-
use extra::future;
23+
use extra::future::Future;
2424

2525
#[deriving(Clone)]
2626
pub enum WriteInstr {
@@ -207,10 +207,10 @@ pub fn future_writer_factory(
207207
(writer_factory, markdown_po)
208208
}
209209

210-
fn future_writer() -> (Writer, future::Future<~str>) {
210+
fn future_writer() -> (Writer, Future<~str>) {
211211
let (port, chan) = comm::stream();
212212
let writer: ~fn(instr: WriteInstr) = |instr| chan.send(instr.clone());
213-
let future = do future::from_fn || {
213+
let future = do Future::from_fn || {
214214
let mut res = ~"";
215215
loop {
216216
match port.recv() {

src/test/bench/msgsend-ring-mutex-arcs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
extern mod extra;
1919

2020
use extra::arc;
21-
use extra::future;
21+
use extra::future::Future;
2222
use extra::time;
2323
use std::cell::Cell;
2424
use std::os;
@@ -94,7 +94,7 @@ fn main() {
9494
let (new_chan, num_port) = init();
9595
let num_chan2 = Cell::new(num_chan.take());
9696
let num_port = Cell::new(num_port);
97-
let new_future = do future::spawn() {
97+
let new_future = do Future::spawn() {
9898
let num_chan = num_chan2.take();
9999
let num_port1 = num_port.take();
100100
thread_ring(i, msg_per_task, num_chan, num_port1)

src/test/bench/msgsend-ring-rw-arcs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
extern mod extra;
1919

2020
use extra::arc;
21-
use extra::future;
21+
use extra::future::Future;
2222
use extra::time;
2323
use std::cell::Cell;
2424
use std::os;
@@ -90,7 +90,7 @@ fn main() {
9090
let (new_chan, num_port) = init();
9191
let num_chan2 = Cell::new(num_chan.take());
9292
let num_port = Cell::new(num_port);
93-
let new_future = do future::spawn {
93+
let new_future = do Future::spawn {
9494
let num_chan = num_chan2.take();
9595
let num_port1 = num_port.take();
9696
thread_ring(i, msg_per_task, num_chan, num_port1)

0 commit comments

Comments
 (0)