1313 *
1414 * An executing Rust program consists of a tree of tasks, each with their own
1515 * stack, and sole ownership of their allocated heap data. Tasks communicate
16- * with each other using ports and channels (see std::rt:: comm for more info
16+ * with each other using ports and channels (see std::comm for more info
1717 * about how communication works).
1818 *
19- * Tasks can be spawned in 3 different modes.
20- *
21- * * Bidirectionally linked: This is the default mode and it's what ```spawn``` does.
22- * Failures will be propagated from parent to child and vice versa.
23- *
24- * * Unidirectionally linked (parent->child): This type of task can be created with
25- * ```spawn_supervised```. In this case, failures are propagated from parent to child
26- * but not the other way around.
27- *
28- * * Unlinked: Tasks can be completely unlinked. These tasks can be created by using
29- * ```spawn_unlinked```. In this case failures are not propagated at all.
30- *
31- * Tasks' failure modes can be further configured. For instance, parent tasks can (un)watch
32- * children failures. Please, refer to TaskBuilder's documentation bellow for more information.
33- *
34- * When a (bi|uni)directionally linked task fails, its failure will be propagated to all tasks
35- * linked to it, this will cause such tasks to fail by a `linked failure`.
19+ * Failure in one task does not propagate to any others (not to parent, not to child).
20+ * Failure propagation is instead handled by using Chan.send() and Port.recv(), which
21+ * will fail if the other end has hung up already.
3622 *
3723 * Task Scheduling:
3824 *
5137 * ```
5238 */
5339
54- #[ allow( missing_doc) ] ;
55-
5640use any:: Any ;
5741use comm:: { Chan , Port } ;
5842use io:: Writer ;
@@ -70,40 +54,24 @@ use str::{Str, SendStr, IntoMaybeOwned};
7054/// Indicates the manner in which a task exited.
7155///
7256/// A task that completes without failing is considered to exit successfully.
73- /// Supervised ancestors and linked siblings may yet fail after this task
74- /// succeeds. Also note that in such a case, it may be nondeterministic whether
75- /// linked failure or successful exit happen first.
7657///
77- /// If you wish for this result's delivery to block until all linked and/or
58+ /// If you wish for this result's delivery to block until all
7859/// children tasks complete, recommend using a result future.
7960pub type TaskResult = Result < ( ) , ~Any > ;
8061
81- /**
82- * Task configuration options
83- *
84- * # Fields
85- *
86- * * watched - Make parent task collect exit status notifications from child
87- * before reporting its own exit status. (This delays the parent
88- * task's death and cleanup until after all transitively watched
89- * children also exit.) True by default.
90- *
91- * * notify_chan - Enable lifecycle notifications on the given channel
92- *
93- * * name - A name for the task-to-be, for identification in failure messages.
94- *
95- * * sched - Specify the configuration of a new scheduler to create the task
96- * in. This is of particular importance for libraries which want to call
97- * into foreign code that blocks. Without doing so in a different
98- * scheduler other tasks will be impeded or even blocked indefinitely.
99- */
62+ /// Task configuration options
10063pub struct TaskOpts {
101- watched : bool ,
64+ /// Enable lifecycle notifications on the given channel
10265 notify_chan : Option < Chan < TaskResult > > ,
66+ /// A name for the task-to-be, for identification in failure messages
10367 name : Option < SendStr > ,
68+ /// The size of the stack for the spawned task
10469 stack_size : Option < uint > ,
70+ /// Task-local logger (see std::logging)
10571 logger : Option < ~Logger > ,
72+ /// Task-local stdout
10673 stdout : Option < ~Writer > ,
74+ /// Task-local stderr
10775 stderr : Option < ~Writer > ,
10876}
10977
@@ -120,6 +88,7 @@ pub struct TaskOpts {
12088// sidestep that whole issue by making builders uncopyable and making
12189// the run function move them in.
12290pub struct TaskBuilder {
91+ /// Options to spawn the new task with
12392 opts : TaskOpts ,
12493 priv gen_body : Option < proc ( v : proc ( ) ) -> proc ( ) > ,
12594 priv nopod : Option < marker:: NoPod > ,
@@ -128,7 +97,6 @@ pub struct TaskBuilder {
12897/**
12998 * Generate the base configuration for spawning a task, off of which more
13099 * configuration methods can be chained.
131- * For example, task().unlinked().spawn is equivalent to spawn_unlinked.
132100 */
133101pub fn task ( ) -> TaskBuilder {
134102 TaskBuilder {
@@ -139,31 +107,13 @@ pub fn task() -> TaskBuilder {
139107}
140108
141109impl TaskBuilder {
142- /// Cause the parent task to collect the child's exit status (and that of
143- /// all transitively-watched grandchildren) before reporting its own.
144- pub fn watched ( & mut self ) {
145- self . opts . watched = true ;
146- }
147-
148- /// Allow the child task to outlive the parent task, at the possible cost
149- /// of the parent reporting success even if the child task fails later.
150- pub fn unwatched ( & mut self ) {
151- self . opts . watched = false ;
152- }
153-
154110 /// Get a future representing the exit status of the task.
155111 ///
156112 /// Taking the value of the future will block until the child task
157113 /// terminates. The future result return value will be created *before* the task is
158114 /// spawned; as such, do not invoke .get() on it directly;
159115 /// rather, store it in an outer variable/list for later use.
160116 ///
161- /// Note that the future returned by this function is only useful for
162- /// obtaining the value of the next task to be spawning with the
163- /// builder. If additional tasks are spawned with the same builder
164- /// then a new result future must be obtained prior to spawning each
165- /// task.
166- ///
167117 /// # Failure
168118 /// Fails if a future_result was already set for this task.
169119 pub fn future_result ( & mut self ) -> Port < TaskResult > {
@@ -187,8 +137,9 @@ impl TaskBuilder {
187137
188138 /// Name the task-to-be. Currently the name is used for identification
189139 /// only in failure messages.
190- pub fn name < S : IntoMaybeOwned < ' static > > ( & mut self , name : S ) {
140+ pub fn named < S : IntoMaybeOwned < ' static > > ( mut self , name : S ) -> TaskBuilder {
191141 self . opts . name = Some ( name. into_maybe_owned ( ) ) ;
142+ self
192143 }
193144
194145 /**
@@ -203,7 +154,7 @@ impl TaskBuilder {
203154 * generator by applying the task body which results from the
204155 * existing body generator to the new body generator.
205156 */
206- pub fn add_wrapper ( & mut self , wrapper : proc ( v : proc ( ) ) -> proc ( ) ) {
157+ pub fn with_wrapper ( mut self , wrapper : proc ( v : proc ( ) ) -> proc ( ) ) -> TaskBuilder {
207158 let prev_gen_body = self . gen_body . take ( ) ;
208159 let prev_gen_body = match prev_gen_body {
209160 Some ( gen) => gen,
@@ -219,6 +170,7 @@ impl TaskBuilder {
219170 f
220171 } ;
221172 self . gen_body = Some ( next_gen_body) ;
173+ self
222174 }
223175
224176 /**
@@ -227,11 +179,6 @@ impl TaskBuilder {
227179 * Sets up a new task with its own call stack and schedules it to run
228180 * the provided unique closure. The task has the properties and behavior
229181 * specified by the task_builder.
230- *
231- * # Failure
232- *
233- * When spawning into a new scheduler, the number of threads requested
234- * must be greater than zero.
235182 */
236183 pub fn spawn ( mut self , f : proc ( ) ) {
237184 let gen_body = self . gen_body . take ( ) ;
@@ -278,13 +225,9 @@ impl TaskOpts {
278225 pub fn new ( ) -> TaskOpts {
279226 /*!
280227 * The default task options
281- *
282- * By default all tasks are supervised by their parent, are spawned
283- * into the same scheduler, and do not post lifecycle notifications.
284228 */
285229
286230 TaskOpts {
287- watched : true ,
288231 notify_chan : None ,
289232 name : None ,
290233 stack_size : None ,
@@ -313,7 +256,7 @@ pub fn try<T:Send>(f: proc() -> T) -> Result<T, ~Any> {
313256 * Execute a function in another task and return either the return value
314257 * of the function or result::err.
315258 *
316- * This is equivalent to task().supervised(). try.
259+ * This is equivalent to task().try.
317260 */
318261
319262 let task = task ( ) ;
@@ -370,9 +313,7 @@ fn test_unnamed_task() {
370313
371314#[ test]
372315fn test_owned_named_task ( ) {
373- let mut t = task ( ) ;
374- t. name ( ~"ada lovelace") ;
375- t. spawn ( proc ( ) {
316+ task ( ) . named ( ~"ada lovelace") . spawn ( proc ( ) {
376317 with_task_name ( |name| {
377318 assert ! ( name. unwrap( ) == "ada lovelace" ) ;
378319 } )
@@ -381,9 +322,7 @@ fn test_owned_named_task() {
381322
382323#[ test]
383324fn test_static_named_task ( ) {
384- let mut t = task ( ) ;
385- t. name ( "ada lovelace" ) ;
386- t. spawn ( proc ( ) {
325+ task ( ) . named ( "ada lovelace" ) . spawn ( proc ( ) {
387326 with_task_name ( |name| {
388327 assert ! ( name. unwrap( ) == "ada lovelace" ) ;
389328 } )
@@ -392,9 +331,7 @@ fn test_static_named_task() {
392331
393332#[ test]
394333fn test_send_named_task ( ) {
395- let mut t = task ( ) ;
396- t. name ( "ada lovelace" . into_maybe_owned ( ) ) ;
397- t. spawn ( proc ( ) {
334+ task ( ) . named ( "ada lovelace" . into_maybe_owned ( ) ) . spawn ( proc ( ) {
398335 with_task_name ( |name| {
399336 assert ! ( name. unwrap( ) == "ada lovelace" ) ;
400337 } )
@@ -411,18 +348,16 @@ fn test_run_basic() {
411348}
412349
413350#[ test]
414- fn test_add_wrapper ( ) {
351+ fn test_with_wrapper ( ) {
415352 let ( po, ch) = Chan :: new ( ) ;
416- let mut b0 = task ( ) ;
417- b0. add_wrapper ( proc ( body) {
353+ task ( ) . with_wrapper ( proc ( body) {
418354 let ch = ch;
419355 let result: proc ( ) = proc ( ) {
420356 body ( ) ;
421357 ch. send ( ( ) ) ;
422358 } ;
423359 result
424- } ) ;
425- b0. spawn ( proc ( ) { } ) ;
360+ } ) . spawn ( proc ( ) { } ) ;
426361 po. recv ( ) ;
427362}
428363
@@ -553,15 +488,11 @@ fn test_child_doesnt_ref_parent() {
553488 fn child_no(x: uint) -> proc() {
554489 return proc() {
555490 if x < generations {
556- let mut t = task();
557- t.unwatched();
558- t.spawn(child_no(x+1));
491+ task().spawn(child_no(x+1));
559492 }
560493 }
561494 }
562- let mut t = task();
563- t.unwatched();
564- t.spawn(child_no(0));
495+ task().spawn(child_no(0));
565496}
566497
567498#[test]
0 commit comments