Skip to content

Commit b178467

Browse files
committed
Clean up task.rs docs and use replace/swap_unwrap
1 parent 9facb15 commit b178467

File tree

1 file changed

+27
-41
lines changed

1 file changed

+27
-41
lines changed

src/libcore/task.rs

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,12 @@ type sched_opts = {
144144
*
145145
* # Fields
146146
*
147-
* * linked - Do not propagate failure to the parent task
147+
* * linked - Propagate failure bidirectionally between child and parent.
148+
* True by default. If both this and 'supervised' are false, then
149+
* either task's failure will not affect the other ("unlinked").
148150
*
149-
* All tasks are linked together via a tree, from parents to children. By
150-
* default children are 'supervised' by their parent and when they fail
151-
* so too will their parents. Settings this flag to false disables that
152-
* behavior.
151+
* * supervised - Propagate failure unidirectionally from parent to child,
152+
* but not from child to parent. False by default.
153153
*
154154
* * notify_chan - Enable lifecycle notifications on the given channel
155155
*
@@ -168,7 +168,7 @@ type sched_opts = {
168168
*/
169169
type task_opts = {
170170
linked: bool,
171-
parented: bool,
171+
supervised: bool,
172172
notify_chan: option<comm::chan<notification>>,
173173
sched: option<sched_opts>,
174174
};
@@ -237,7 +237,7 @@ impl task_builder for task_builder {
237237
*/
238238
fn supervised() -> task_builder {
239239
task_builder({
240-
opts: { linked: false, parented: true with self.opts },
240+
opts: { linked: false, supervised: true with self.opts },
241241
can_not_copy: none,
242242
with *self.consume()
243243
})
@@ -248,7 +248,7 @@ impl task_builder for task_builder {
248248
*/
249249
fn linked() -> task_builder {
250250
task_builder({
251-
opts: { linked: true, parented: false with self.opts },
251+
opts: { linked: true, supervised: false with self.opts },
252252
can_not_copy: none,
253253
with *self.consume()
254254
})
@@ -342,9 +342,7 @@ impl task_builder for task_builder {
342342
fn spawn_with<A: send>(+arg: A, +f: fn~(+A)) {
343343
let arg = ~mut some(arg);
344344
do self.spawn {
345-
let mut my_arg = none;
346-
my_arg <-> *arg;
347-
f(option::unwrap(my_arg))
345+
f(option::swap_unwrap(arg))
348346
}
349347
}
350348

@@ -385,7 +383,7 @@ fn default_task_opts() -> task_opts {
385383

386384
{
387385
linked: true,
388-
parented: false,
386+
supervised: false,
389387
notify_chan: none,
390388
sched: none
391389
}
@@ -599,14 +597,14 @@ unsafe fn atomically<U>(f: fn() -> U) -> U {
599597
*
600598
* (2) The "tcb" is a per-task control structure that tracks a task's spawn
601599
* configuration. It contains a reference to its taskgroup_arc, a
602-
* a reference to its node in the ancestor list (below), a flag for
600+
* reference to its node in the ancestor list (below), a flag for
603601
* whether it's part of the 'main'/'root' taskgroup, and an optionally
604602
* configured notification port. These are stored in TLS.
605603
*
606604
* (3) The "ancestor_list" is a cons-style list of arc::exclusives which
607605
* tracks 'generations' of taskgroups -- a group's ancestors are groups
608606
* which (directly or transitively) spawn_supervised-ed them. Each task
609-
* recorded in the 'descendants' of each of its ancestor groups.
607+
* is recorded in the 'descendants' of each of its ancestor groups.
610608
*
611609
* Spawning a supervised task is O(n) in the number of generations still
612610
* alive, and exiting (by success or failure) that task is also O(n).
@@ -753,8 +751,7 @@ fn each_ancestor(list: &mut ancestor_list,
753751
forward_blk: fn(taskgroup_inner) -> bool,
754752
last_generation: uint) -> bool {
755753
// Need to swap the list out to use it, to appease borrowck.
756-
let mut tmp_list = ancestor_list(none);
757-
*list <-> tmp_list;
754+
let tmp_list = util::replace(list, ancestor_list(none));
758755
let (coalesce_this, early_break) =
759756
iterate(tmp_list, bail_opt, forward_blk, last_generation);
760757
// What should our next ancestor end up being?
@@ -841,9 +838,9 @@ fn each_ancestor(list: &mut ancestor_list,
841838
need_unwind = need_unwind || !do_continue;
842839
// Tell caller whether or not to coalesce and/or unwind
843840
if nobe_is_dead {
844-
let mut rest = ancestor_list(none);
845841
// Swap the list out here; the caller replaces us with it.
846-
nobe.ancestors <-> rest;
842+
let rest = util::replace(&mut nobe.ancestors,
843+
ancestor_list(none));
847844
(some(rest), need_unwind)
848845
} else {
849846
(none, need_unwind)
@@ -854,11 +851,8 @@ fn each_ancestor(list: &mut ancestor_list,
854851
// Wrapper around exclusive::with that appeases borrowck.
855852
fn with_parent_tg<U>(parent_group: &mut option<taskgroup_arc>,
856853
blk: fn(taskgroup_inner) -> U) -> U {
857-
let mut tmp = none;
858-
*parent_group <-> tmp;
859854
// If this trips, more likely the problem is 'blk' failed inside.
860-
assert tmp.is_some();
861-
let tmp_arc = option::unwrap(tmp);
855+
let tmp_arc = option::swap_unwrap(parent_group);
862856
let result = do access_group(tmp_arc) |tg_opt| { blk(tg_opt) };
863857
*parent_group <- some(tmp_arc);
864858
result
@@ -923,8 +917,7 @@ class auto_notify {
923917

924918
fn enlist_in_taskgroup(state: taskgroup_inner, me: *rust_task,
925919
is_member: bool) -> bool {
926-
let mut newstate = none;
927-
*state <-> newstate;
920+
let newstate = util::replace(state, none);
928921
// If 'none', the group was failing. Can't enlist.
929922
if newstate.is_some() {
930923
let group = option::unwrap(newstate);
@@ -939,8 +932,7 @@ fn enlist_in_taskgroup(state: taskgroup_inner, me: *rust_task,
939932

940933
// NB: Runs in destructor/post-exit context. Can't 'fail'.
941934
fn leave_taskgroup(state: taskgroup_inner, me: *rust_task, is_member: bool) {
942-
let mut newstate = none;
943-
*state <-> newstate;
935+
let newstate = util::replace(state, none);
944936
// If 'none', already failing and we've already gotten a kill signal.
945937
if newstate.is_some() {
946938
let group = option::unwrap(newstate);
@@ -960,8 +952,7 @@ fn kill_taskgroup(state: taskgroup_inner, me: *rust_task, is_main: bool) {
960952
// so if we're failing, all concurrently exiting tasks must wait for us.
961953
// To do it differently, we'd have to use the runtime's task refcounting,
962954
// but that could leave task structs around long after their task exited.
963-
let mut newstate = none;
964-
*state <-> newstate;
955+
let newstate = util::replace(state, none);
965956
// Might already be none, if somebody is failing simultaneously.
966957
// That's ok; only one task needs to do the dirty work. (Might also
967958
// see 'none' if somebody already failed and we got a kill signal.)
@@ -1059,8 +1050,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
10591050
// alt ancestors
10601051
// some(ancestor_arc) { ancestor_list(some(ancestor_arc.clone())) }
10611052
// none { ancestor_list(none) }
1062-
let mut tmp = none;
1063-
**ancestors <-> tmp;
1053+
let tmp = util::replace(&mut **ancestors, none);
10641054
if tmp.is_some() {
10651055
let ancestor_arc = option::unwrap(tmp);
10661056
let result = ancestor_arc.clone();
@@ -1074,16 +1064,14 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
10741064

10751065
fn spawn_raw(opts: task_opts, +f: fn~()) {
10761066
let (child_tg, ancestors, is_main) =
1077-
gen_child_taskgroup(opts.linked, opts.parented);
1067+
gen_child_taskgroup(opts.linked, opts.supervised);
10781068

10791069
unsafe {
1080-
let child_data_ptr = ~mut some((child_tg, ancestors, f));
1070+
let child_data = ~mut some((child_tg, ancestors, f));
10811071
// Being killed with the unsafe task/closure pointers would leak them.
10821072
do unkillable {
10831073
// Agh. Get move-mode items into the closure. FIXME (#2829)
1084-
let mut child_data = none;
1085-
*child_data_ptr <-> child_data;
1086-
let (child_tg, ancestors, f) = option::unwrap(child_data);
1074+
let (child_tg, ancestors, f) = option::swap_unwrap(child_data);
10871075
// Create child task.
10881076
let new_task = alt opts.sched {
10891077
none { rustrt::new_task() }
@@ -1116,12 +1104,10 @@ fn spawn_raw(opts: task_opts, +f: fn~()) {
11161104
-ancestors: ancestor_list, is_main: bool,
11171105
notify_chan: option<comm::chan<notification>>,
11181106
-f: fn~()) -> fn~() {
1119-
let child_tg_ptr = ~mut some((child_arc, ancestors));
1107+
let child_data = ~mut some((child_arc, ancestors));
11201108
return fn~() {
11211109
// Agh. Get move-mode items into the closure. FIXME (#2829)
1122-
let mut tg_data_opt = none;
1123-
*child_tg_ptr <-> tg_data_opt;
1124-
let mut (child_arc, ancestors) = option::unwrap(tg_data_opt);
1110+
let mut (child_arc, ancestors) = option::swap_unwrap(child_data);
11251111
// Child task runs this code.
11261112

11271113
// Even if the below code fails to kick the child off, we must
@@ -1528,7 +1514,7 @@ fn test_spawn_linked_sup_fail_up() { // child fails; parent fails
15281514
// they don't make sense (redundant with task().supervised()).
15291515
let b0 = task();
15301516
let b1 = task_builder({
1531-
opts: { linked: true, parented: true with b0.opts },
1517+
opts: { linked: true, supervised: true with b0.opts },
15321518
can_not_copy: none,
15331519
with *b0
15341520
});
@@ -1541,7 +1527,7 @@ fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
15411527
// they don't make sense (redundant with task().supervised()).
15421528
let b0 = task();
15431529
let b1 = task_builder({
1544-
opts: { linked: true, parented: true with b0.opts },
1530+
opts: { linked: true, supervised: true with b0.opts },
15451531
can_not_copy: none,
15461532
with *b0
15471533
});

0 commit comments

Comments
 (0)