Skip to content

Commit b2d5acd

Browse files
committed
Merge remote-tracking branch 'brson/futures'
2 parents d82ddc2 + d29962f commit b2d5acd

24 files changed

+66
-122
lines changed

src/libcore/core.rc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ pub mod task {
181181
pub mod spawn;
182182
pub mod rt;
183183
}
184-
pub mod future;
185184
pub mod pipes;
186185

187186
// Runtime and language-primitive support

src/libcore/private.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -581,16 +581,20 @@ pub mod tests {
581581

582582
for uint::range(0, num_tasks) |_i| {
583583
let total = total.clone();
584-
futures.push(future::spawn(|move total| {
584+
let (chan, port) = pipes::stream();
585+
futures.push(move port);
586+
587+
do task::spawn |move total, move chan| {
585588
for uint::range(0, count) |_i| {
586589
do total.with |count| {
587590
**count += 1;
588591
}
589592
}
590-
}));
593+
chan.send(());
594+
}
591595
};
592596

593-
for futures.each |f| { f.get() }
597+
for futures.each |f| { f.recv() }
594598

595599
do total.with |total| {
596600
assert **total == num_tasks * count
@@ -642,7 +646,7 @@ pub mod tests {
642646
// Have to get rid of our reference before blocking.
643647
{ let _x = move x; } // FIXME(#3161) util::ignore doesn't work here
644648
let res = option::swap_unwrap(&mut res);
645-
future::get(&res);
649+
res.recv();
646650
}
647651

648652
#[test] #[should_fail] #[ignore(cfg(windows))]
@@ -657,7 +661,7 @@ pub mod tests {
657661
}
658662
assert unwrap_exclusive(move x) == ~~"hello";
659663
let res = option::swap_unwrap(&mut res);
660-
future::get(&res);
664+
res.recv();
661665
}
662666

663667
#[test] #[ignore(cfg(windows))]

src/libcore/task.rs

Lines changed: 15 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use cmp::Eq;
3232
use result::Result;
3333
use pipes::{stream, Chan, Port};
3434
use local_data_priv::{local_get, local_set};
35+
use util::replace;
3536

3637
use rt::task_id;
3738
use rt::rust_task;
@@ -72,25 +73,6 @@ impl TaskResult : Eq {
7273
pure fn ne(other: &TaskResult) -> bool { !self.eq(other) }
7374
}
7475

75-
/// A message type for notifying of task lifecycle events
76-
pub enum Notification {
77-
/// Sent when a task exits with the task handle and result
78-
Exit(Task, TaskResult)
79-
}
80-
81-
impl Notification : cmp::Eq {
82-
pure fn eq(other: &Notification) -> bool {
83-
match self {
84-
Exit(e0a, e1a) => {
85-
match (*other) {
86-
Exit(e0b, e1b) => e0a == e0b && e1a == e1b
87-
}
88-
}
89-
}
90-
}
91-
pure fn ne(other: &Notification) -> bool { !self.eq(other) }
92-
}
93-
9476
/// Scheduler modes
9577
pub enum SchedMode {
9678
/// All tasks run in the same OS thread
@@ -200,7 +182,7 @@ pub type SchedOpts = {
200182
pub type TaskOpts = {
201183
linked: bool,
202184
supervised: bool,
203-
mut notify_chan: Option<Chan<Notification>>,
185+
mut notify_chan: Option<Chan<TaskResult>>,
204186
sched: Option<SchedOpts>,
205187
};
206188

@@ -246,11 +228,7 @@ priv impl TaskBuilder {
246228
fail ~"Cannot copy a task_builder"; // Fake move mode on self
247229
}
248230
self.consumed = true;
249-
let notify_chan = if self.opts.notify_chan.is_none() {
250-
None
251-
} else {
252-
Some(option::swap_unwrap(&mut self.opts.notify_chan))
253-
};
231+
let notify_chan = replace(&mut self.opts.notify_chan, None);
254232
TaskBuilder({
255233
opts: {
256234
linked: self.opts.linked,
@@ -271,11 +249,7 @@ impl TaskBuilder {
271249
* the other will not be killed.
272250
*/
273251
fn unlinked() -> TaskBuilder {
274-
let notify_chan = if self.opts.notify_chan.is_none() {
275-
None
276-
} else {
277-
Some(option::swap_unwrap(&mut self.opts.notify_chan))
278-
};
252+
let notify_chan = replace(&mut self.opts.notify_chan, None);
279253
TaskBuilder({
280254
opts: {
281255
linked: false,
@@ -293,11 +267,7 @@ impl TaskBuilder {
293267
* the child.
294268
*/
295269
fn supervised() -> TaskBuilder {
296-
let notify_chan = if self.opts.notify_chan.is_none() {
297-
None
298-
} else {
299-
Some(option::swap_unwrap(&mut self.opts.notify_chan))
300-
};
270+
let notify_chan = replace(&mut self.opts.notify_chan, None);
301271
TaskBuilder({
302272
opts: {
303273
linked: false,
@@ -314,11 +284,7 @@ impl TaskBuilder {
314284
* other will be killed.
315285
*/
316286
fn linked() -> TaskBuilder {
317-
let notify_chan = if self.opts.notify_chan.is_none() {
318-
None
319-
} else {
320-
Some(option::swap_unwrap(&mut self.opts.notify_chan))
321-
};
287+
let notify_chan = replace(&mut self.opts.notify_chan, None);
322288
TaskBuilder({
323289
opts: {
324290
linked: true,
@@ -348,7 +314,7 @@ impl TaskBuilder {
348314
* # Failure
349315
* Fails if a future_result was already set for this task.
350316
*/
351-
fn future_result(blk: fn(v: future::Future<TaskResult>)) -> TaskBuilder {
317+
fn future_result(blk: fn(v: Port<TaskResult>)) -> TaskBuilder {
352318
// FIXME (#3725): Once linked failure and notification are
353319
// handled in the library, I can imagine implementing this by just
354320
// registering an arbitrary number of task::on_exit handlers and
@@ -359,13 +325,9 @@ impl TaskBuilder {
359325
}
360326
361327
// Construct the future and give it to the caller.
362-
let (notify_pipe_ch, notify_pipe_po) = stream::<Notification>();
328+
let (notify_pipe_ch, notify_pipe_po) = stream::<TaskResult>();
363329
364-
blk(do future::from_fn |move notify_pipe_po| {
365-
match notify_pipe_po.recv() {
366-
Exit(_, result) => result
367-
}
368-
});
330+
blk(move notify_pipe_po);
369331
370332
// Reconfigure self to use a notify channel.
371333
TaskBuilder({
@@ -381,11 +343,7 @@ impl TaskBuilder {
381343
}
382344
/// Configure a custom scheduler mode for the task.
383345
fn sched_mode(mode: SchedMode) -> TaskBuilder {
384-
let notify_chan = if self.opts.notify_chan.is_none() {
385-
None
386-
} else {
387-
Some(option::swap_unwrap(&mut self.opts.notify_chan))
388-
};
346+
let notify_chan = replace(&mut self.opts.notify_chan, None);
389347
TaskBuilder({
390348
opts: {
391349
linked: self.opts.linked,
@@ -412,11 +370,7 @@ impl TaskBuilder {
412370
*/
413371
fn add_wrapper(wrapper: fn@(v: fn~()) -> fn~()) -> TaskBuilder {
414372
let prev_gen_body = self.gen_body;
415-
let notify_chan = if self.opts.notify_chan.is_none() {
416-
None
417-
} else {
418-
Some(option::swap_unwrap(&mut self.opts.notify_chan))
419-
};
373+
let notify_chan = replace(&mut self.opts.notify_chan, None);
420374
TaskBuilder({
421375
opts: {
422376
linked: self.opts.linked,
@@ -447,13 +401,7 @@ impl TaskBuilder {
447401
* must be greater than zero.
448402
*/
449403
fn spawn(f: fn~()) {
450-
let notify_chan = if self.opts.notify_chan.is_none() {
451-
None
452-
} else {
453-
let swapped_notify_chan =
454-
option::swap_unwrap(&mut self.opts.notify_chan);
455-
Some(move swapped_notify_chan)
456-
};
404+
let notify_chan = replace(&mut self.opts.notify_chan, None);
457405
let x = self.consume();
458406
let opts = {
459407
linked: x.opts.linked,
@@ -532,7 +480,7 @@ impl TaskBuilder {
532480
do fr_task_builder.spawn |move f| {
533481
comm::send(ch, f());
534482
}
535-
match future::get(&option::unwrap(move result)) {
483+
match option::unwrap(move result).recv() {
536484
Success => result::Ok(comm::recv(po)),
537485
Failure => result::Err(())
538486
}
@@ -949,14 +897,14 @@ fn test_add_wrapper() {
949897
fn test_future_result() {
950898
let mut result = None;
951899
do task().future_result(|+r| { result = Some(move r); }).spawn { }
952-
assert future::get(&option::unwrap(move result)) == Success;
900+
assert option::unwrap(move result).recv() == Success;
953901

954902
result = None;
955903
do task().future_result(|+r|
956904
{ result = Some(move r); }).unlinked().spawn {
957905
fail;
958906
}
959-
assert future::get(&option::unwrap(move result)) == Failure;
907+
assert option::unwrap(move result).recv() == Failure;
960908
}
961909

962910
#[test] #[should_fail] #[ignore(cfg(windows))]

src/libcore/task/spawn.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -320,15 +320,15 @@ fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
320320
}
321321

322322
struct AutoNotify {
323-
notify_chan: Chan<Notification>,
323+
notify_chan: Chan<TaskResult>,
324324
mut failed: bool,
325325
drop {
326326
let result = if self.failed { Failure } else { Success };
327-
self.notify_chan.send(Exit(get_task(), result));
327+
self.notify_chan.send(result);
328328
}
329329
}
330330

331-
fn AutoNotify(chan: Chan<Notification>) -> AutoNotify {
331+
fn AutoNotify(chan: Chan<TaskResult>) -> AutoNotify {
332332
AutoNotify {
333333
notify_chan: move chan,
334334
failed: true // Un-set above when taskgroup successfully made.
@@ -532,7 +532,7 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
532532
// (4) ...and runs the provided body function.
533533
fn make_child_wrapper(child: *rust_task, child_arc: TaskGroupArc,
534534
ancestors: AncestorList, is_main: bool,
535-
notify_chan: Option<Chan<Notification>>,
535+
notify_chan: Option<Chan<TaskResult>>,
536536
f: fn~()) -> fn~() {
537537
let child_data = ~mut Some((move child_arc, move ancestors));
538538
return fn~(move notify_chan, move child_data, move f) {
@@ -660,36 +660,30 @@ fn test_spawn_raw_unsupervise() {
660660
#[test]
661661
#[ignore(cfg(windows))]
662662
fn test_spawn_raw_notify_success() {
663-
let (task_ch, task_po) = pipes::stream();
664663
let (notify_ch, notify_po) = pipes::stream();
665664

666665
let opts = {
667666
notify_chan: Some(move notify_ch),
668667
.. default_task_opts()
669668
};
670-
do spawn_raw(move opts) |move task_ch| {
671-
task_ch.send(get_task());
669+
do spawn_raw(move opts) {
672670
}
673-
let task_ = task_po.recv();
674-
assert notify_po.recv() == Exit(task_, Success);
671+
assert notify_po.recv() == Success;
675672
}
676673

677674
#[test]
678675
#[ignore(cfg(windows))]
679676
fn test_spawn_raw_notify_failure() {
680677
// New bindings for these
681-
let (task_ch, task_po) = pipes::stream();
682678
let (notify_ch, notify_po) = pipes::stream();
683679

684680
let opts = {
685681
linked: false,
686682
notify_chan: Some(move notify_ch),
687683
.. default_task_opts()
688684
};
689-
do spawn_raw(move opts) |move task_ch| {
690-
task_ch.send(get_task());
685+
do spawn_raw(move opts) {
691686
fail;
692687
}
693-
let task_ = task_po.recv();
694-
assert notify_po.recv() == Exit(task_, Failure);
688+
assert notify_po.recv() == Failure;
695689
}

src/libstd/arc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ mod tests {
651651
}
652652

653653
// Wait for children to pass their asserts
654-
for vec::each(children) |r| { future::get(r); }
654+
for vec::each(children) |r| { r.recv(); }
655655

656656
// Wait for writer to finish
657657
p.recv();

src/libcore/future.rs renamed to src/libstd/future.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*/
1818

1919
use either::Either;
20-
use pipes::recv;
20+
use pipes::{recv, oneshot, ChanOne, PortOne, send_one, recv_one};
2121
use cast::copy_lifetime;
2222

2323
#[doc = "The future type"]
@@ -67,7 +67,7 @@ pub fn from_value<A>(val: A) -> Future<A> {
6767
Future {state: Forced(~(move val))}
6868
}
6969

70-
pub fn from_port<A:Send>(port: future_pipe::client::waiting<A>) ->
70+
pub fn from_port<A:Send>(port: PortOne<A>) ->
7171
Future<A> {
7272
/*!
7373
* Create a future from a port
@@ -82,7 +82,7 @@ pub fn from_port<A:Send>(port: future_pipe::client::waiting<A>) ->
8282
port_ <-> *port;
8383
let port = option::unwrap(move port_);
8484
match recv(move port) {
85-
future_pipe::completed(move data) => move data
85+
oneshot::send(move data) => move data
8686
}
8787
}
8888
}
@@ -107,9 +107,15 @@ pub fn spawn<A:Send>(blk: fn~() -> A) -> Future<A> {
107107
* value of the future.
108108
*/
109109

110-
from_port(pipes::spawn_service_recv(future_pipe::init, |move blk, ch| {
111-
future_pipe::server::completed(move ch, blk());
112-
}))
110+
let (chan, port) = oneshot::init();
111+
112+
let chan = ~mut Some(move chan);
113+
do task::spawn |move blk, move chan| {
114+
let chan = option::swap_unwrap(&mut *chan);
115+
send_one(move chan, blk());
116+
}
117+
118+
return from_port(move port);
113119
}
114120

115121
pub fn get_ref<A>(future: &r/Future<A>) -> &r/A {
@@ -162,12 +168,6 @@ pub fn with<A,B>(future: &Future<A>, blk: fn((&A)) -> B) -> B {
162168
blk(get_ref(future))
163169
}
164170

165-
proto! future_pipe (
166-
waiting:recv<T:Send> {
167-
completed(T) -> !
168-
}
169-
)
170-
171171
#[allow(non_implicitly_copyable_typarams)]
172172
pub mod test {
173173
#[test]
@@ -178,8 +178,8 @@ pub mod test {
178178

179179
#[test]
180180
pub fn test_from_port() {
181-
let (po, ch) = future_pipe::init();
182-
future_pipe::server::completed(move ch, ~"whale");
181+
let (ch, po) = oneshot::init();
182+
send_one(move ch, ~"whale");
183183
let f = from_port(move po);
184184
assert get(&f) == ~"whale";
185185
}

src/libstd/std.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub mod cell;
5353
pub mod sync;
5454
pub mod arc;
5555
pub mod comm;
56+
pub mod future;
5657

5758
// Collections
5859

0 commit comments

Comments
 (0)