Skip to content

Commit 3fc4e4c

Browse files
committed
---
yaml --- r: 90031 b: refs/heads/master c: f1bec46 h: refs/heads/master i: 90029: fbdb6f4 90027: 8a9a94c 90023: fd75b7e 90015: 7c1b61a v: v3
1 parent e55f6a3 commit 3fc4e4c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+795
-2701
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 98f47aa67da3286f186d217e99634623d346e0b5
2+
refs/heads/master: f1bec46e15c245b9e9f5c0cf64bf2ac6a1882066
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d3e57dca68fde4effdda3e4ae2887aa535fcd6
55
refs/heads/try: b160761e35efcd1207112b3b782c06633cf441a8

trunk/doc/rust.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2349,9 +2349,9 @@ Indices are zero-based, and may be of any integral type. Vector access
23492349
is bounds-checked at run-time. When the check fails, it will put the
23502350
task in a _failing state_.
23512351

2352-
~~~~
2352+
~~~~ {.xfail-test}
23532353
# use std::task;
2354-
# do task::spawn_unlinked {
2354+
# do task::spawn {
23552355
23562356
([1, 2, 3, 4])[0];
23572357
(["a", "b"])[10]; // fails

trunk/doc/tutorial-tasks.md

Lines changed: 1 addition & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -402,22 +402,6 @@ freeing memory along the way---and then exits. Unlike exceptions in C++,
402402
exceptions in Rust are unrecoverable within a single task: once a task fails,
403403
there is no way to "catch" the exception.
404404

405-
All tasks are, by default, _linked_ to each other. That means that the fates
406-
of all tasks are intertwined: if one fails, so do all the others.
407-
408-
~~~{.xfail-test .linked-failure}
409-
# use std::task::spawn;
410-
# use std::task;
411-
# fn do_some_work() { loop { task::yield() } }
412-
# do task::try {
413-
// Create a child task that fails
414-
do spawn { fail!() }
415-
416-
// This will also fail because the task we spawned failed
417-
do_some_work();
418-
# };
419-
~~~
420-
421405
While it isn't possible for a task to recover from failure, tasks may notify
422406
each other of failure. The simplest way of handling task failure is with the
423407
`try` function, which is similar to `spawn`, but immediately blocks waiting
@@ -464,101 +448,7 @@ it trips, indicates an unrecoverable logic error); in other cases you
464448
might want to contain the failure at a certain boundary (perhaps a
465449
small piece of input from the outside world, which you happen to be
466450
processing in parallel, is malformed and its processing task can't
467-
proceed). Hence, you will need different _linked failure modes_.
468-
469-
## Failure modes
470-
471-
By default, task failure is _bidirectionally linked_, which means that if
472-
either task fails, it kills the other one.
473-
474-
~~~{.xfail-test .linked-failure}
475-
# use std::task;
476-
# use std::comm::oneshot;
477-
# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }
478-
# do task::try {
479-
do spawn {
480-
do spawn {
481-
fail!(); // All three tasks will fail.
482-
}
483-
sleep_forever(); // Will get woken up by force, then fail
484-
}
485-
sleep_forever(); // Will get woken up by force, then fail
486-
# };
487-
~~~
488-
489-
If you want parent tasks to be able to kill their children, but do not want a
490-
parent to fail automatically if one of its child task fails, you can call
491-
`task::spawn_supervised` for _unidirectionally linked_ failure. The
492-
function `task::try`, which we saw previously, uses `spawn_supervised`
493-
internally, with additional logic to wait for the child task to finish
494-
before returning. Hence:
495-
496-
~~~{.xfail-test .linked-failure}
497-
# use std::comm::{stream, Chan, Port};
498-
# use std::comm::oneshot;
499-
# use std::task::{spawn, try};
500-
# use std::task;
501-
# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }
502-
# do task::try {
503-
let (receiver, sender): (Port<int>, Chan<int>) = stream();
504-
do spawn { // Bidirectionally linked
505-
// Wait for the supervised child task to exist.
506-
let message = receiver.recv();
507-
// Kill both it and the parent task.
508-
assert!(message != 42);
509-
}
510-
do try { // Unidirectionally linked
511-
sender.send(42);
512-
sleep_forever(); // Will get woken up by force
513-
}
514-
// Flow never reaches here -- parent task was killed too.
515-
# };
516-
~~~
517-
518-
Supervised failure is useful in any situation where one task manages
519-
multiple fallible child tasks, and the parent task can recover
520-
if any child fails. On the other hand, if the _parent_ (supervisor) fails,
521-
then there is nothing the children can do to recover, so they should
522-
also fail.
523-
524-
Supervised task failure propagates across multiple generations even if
525-
an intermediate generation has already exited:
526-
527-
~~~{.xfail-test .linked-failure}
528-
# use std::task;
529-
# use std::comm::oneshot;
530-
# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }
531-
# fn wait_for_a_while() { for _ in range(0, 1000u) { task::yield() } }
532-
# do task::try::<int> {
533-
do task::spawn_supervised {
534-
do task::spawn_supervised {
535-
sleep_forever(); // Will get woken up by force, then fail
536-
}
537-
// Intermediate task immediately exits
538-
}
539-
wait_for_a_while();
540-
fail!(); // Will kill grandchild even if child has already exited
541-
# };
542-
~~~
543-
544-
Finally, tasks can be configured to not propagate failure to each
545-
other at all, using `task::spawn_unlinked` for _isolated failure_.
546-
547-
~~~{.xfail-test .linked-failure}
548-
# use std::task;
549-
# fn random() -> uint { 100 }
550-
# fn sleep_for(i: uint) { for _ in range(0, i) { task::yield() } }
551-
# do task::try::<()> {
552-
let (time1, time2) = (random(), random());
553-
do task::spawn_unlinked {
554-
sleep_for(time2); // Won't get forced awake
555-
fail!();
556-
}
557-
sleep_for(time1); // Won't get forced awake
558-
fail!();
559-
// It will take MAX(time1,time2) for the program to finish.
560-
# };
561-
~~~
451+
proceed).
562452

563453
## Creating a task with a bi-directional communication path
564454

trunk/mk/docs.mk

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,12 @@ RUSTDOC = $(HBIN2_H_$(CFG_BUILD))/rustdoc$(X_$(CFG_BUILD))
215215
# $(1) - The crate name (std/extra)
216216
# $(2) - The crate file
217217
# $(3) - The relevant host build triple (to depend on libstd)
218+
#
219+
# Passes --cfg stage2 to rustdoc because it uses the stage2 librustc.
218220
define libdoc
219221
doc/$(1)/index.html: $$(RUSTDOC) $$(TLIB2_T_$(3)_H_$(3))/$(CFG_STDLIB_$(3))
220222
@$$(call E, rustdoc: $$@)
221-
$(Q)$(RUSTDOC) $(2)
223+
$(Q)$(RUSTDOC) --cfg stage2 $(2)
222224

223225
DOCS += doc/$(1)/index.html
224226
endef

trunk/src/libextra/arc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ mod tests {
655655
let arc2 = ~arc.clone();
656656
let (p, c) = comm::stream();
657657

658-
do task::spawn_unlinked || {
658+
do spawn {
659659
let _ = p.recv();
660660
do arc2.access_cond |one, cond| {
661661
cond.signal();

trunk/src/libextra/comm.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ pub fn rendezvous<T: Send>() -> (SyncPort<T>, SyncChan<T>) {
137137
mod test {
138138
use comm::{DuplexStream, rendezvous};
139139
use std::rt::test::run_in_uv_task;
140-
use std::task::spawn_unlinked;
141140

142141

143142
#[test]
@@ -177,7 +176,7 @@ mod test {
177176
#[test]
178177
fn send_and_fail_and_try_recv() {
179178
let (port, chan) = rendezvous();
180-
do spawn_unlinked {
179+
do spawn {
181180
chan.duplex_stream.send(()); // Can't access this field outside this module
182181
fail!()
183182
}
@@ -187,7 +186,7 @@ mod test {
187186
#[test]
188187
fn try_send_and_recv_then_fail_before_ack() {
189188
let (port, chan) = rendezvous();
190-
do spawn_unlinked {
189+
do spawn {
191190
port.duplex_stream.recv();
192191
fail!()
193192
}
@@ -198,7 +197,7 @@ mod test {
198197
#[should_fail]
199198
fn send_and_recv_then_fail_before_ack() {
200199
let (port, chan) = rendezvous();
201-
do spawn_unlinked {
200+
do spawn {
202201
port.duplex_stream.recv();
203202
fail!()
204203
}

trunk/src/libextra/future.rs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
use std::cell::Cell;
2929
use std::comm::{PortOne, oneshot};
30-
use std::task;
3130
use std::util::replace;
3231

3332
/// A type encapsulating the result of a computation which may not be complete
@@ -130,29 +129,12 @@ impl<A:Send> Future<A> {
130129

131130
let (port, chan) = oneshot();
132131

133-
do task::spawn_with(chan) |chan| {
132+
do spawn {
134133
chan.send(blk());
135134
}
136135

137136
Future::from_port(port)
138137
}
139-
140-
pub fn spawn_with<B: Send>(v: B, blk: proc(B) -> A) -> Future<A> {
141-
/*!
142-
* Create a future from a unique closure taking one argument.
143-
*
144-
* The closure and its argument will be moved into a new task. The
145-
* closure will be run and its result used as the value of the future.
146-
*/
147-
148-
let (port, chan) = oneshot();
149-
150-
do task::spawn_with((v, chan)) |(v, chan)| {
151-
chan.send(blk(v));
152-
}
153-
154-
Future::from_port(port)
155-
}
156138
}
157139

158140
#[cfg(test)]
@@ -207,12 +189,6 @@ mod test {
207189
assert_eq!(f.get(), ~"bale");
208190
}
209191
210-
#[test]
211-
fn test_spawn_with() {
212-
let mut f = Future::spawn_with(~"gale", |s| { s });
213-
assert_eq!(f.get(), ~"gale");
214-
}
215-
216192
#[test]
217193
#[should_fail]
218194
fn test_futurefail() {

0 commit comments

Comments
 (0)