@@ -591,21 +591,16 @@ class taskgroup {
591
591
let my_pos: uint ;
592
592
// let parent_group: taskgroup_arc; // TODO(bblum)
593
593
// TODO XXX bblum: add a list of empty slots to get runtime back
594
- // Indicates whether this is the main (root) taskgroup. If so, failure
595
- // here should take down the entire runtime.
596
- let is_main: bool ;
597
- new ( -tasks: taskgroup_arc, me: * rust_task, my_pos: uint, is_main: bool ) {
598
- self . tasks = tasks;
599
- self . me = me;
600
- self . my_pos = my_pos;
601
- self . is_main = is_main;
594
+ let mut failed: bool ;
595
+ new ( -tasks: taskgroup_arc, me: * rust_task, my_pos: uint) {
596
+ self . tasks = tasks; self . me = me; self . my_pos = my_pos;
597
+ self . failed = true ; // This will get un-set on successful exit.
602
598
}
603
599
// Runs on task exit.
604
600
drop {
605
- // If we are failing, the whole taskgroup needs to die.
606
- if rustrt:: rust_task_is_unwinding ( self . me ) {
601
+ if self. failed {
607
602
// Take everybody down with us.
608
- kill_taskgroup ( self . tasks , self . me , self . my_pos , self . is_main ) ;
603
+ kill_taskgroup( self . tasks , self . me , self . my_pos ) ;
609
604
} else {
610
605
// Remove ourselves from the group.
611
606
leave_taskgroup ( self . tasks , self . me , self . my_pos ) ;
@@ -647,8 +642,7 @@ fn leave_taskgroup(group_arc: taskgroup_arc, me: *rust_task, index: uint) {
647
642
}
648
643
649
644
// NB: Runs in destructor/post-exit context. Can't 'fail'.
650
- fn kill_taskgroup ( group_arc : taskgroup_arc , me : * rust_task , index : uint ,
651
- is_main : bool ) {
645
+ fn kill_taskgroup ( group_arc : taskgroup_arc , me : * rust_task , index : uint ) {
652
646
// NB: We could do the killing iteration outside of the group arc, by
653
647
// having "let mut newstate" here, swapping inside, and iterating after.
654
648
// But that would let other exiting tasks fall-through and exit while we
@@ -673,40 +667,32 @@ fn kill_taskgroup(group_arc: taskgroup_arc, me: *rust_task, index: uint,
673
667
rustrt:: rust_task_kill_other( task) ;
674
668
} ;
675
669
}
676
- // Only one task should ever do this.
677
- if is_main {
678
- rustrt:: rust_task_kill_all ( me) ;
679
- }
680
670
} ;
681
- // (note: multiple tasks may reach this point)
682
671
} ;
683
672
}
684
673
685
- fn share_parent_taskgroup ( ) -> ( taskgroup_arc , bool ) {
674
+ fn share_parent_taskgroup ( ) -> taskgroup_arc {
686
675
let me = rustrt:: rust_get_task ( ) ;
687
676
alt unsafe { local_get ( me, taskgroup_key) } {
688
677
some ( group) {
689
- // Clone the shared state for the child; propagate main-ness.
690
- ( group. tasks . clone ( ) , group. is_main )
678
+ group. tasks . clone ( )
691
679
}
692
680
none {
693
- // Main task, doing first spawn ever.
681
+ /* Main task, doing first spawn ever. */
694
682
let tasks = arc:: exclusive ( some ( dvec:: from_elem ( some ( me) ) ) ) ;
695
- let group = @taskgroup ( tasks. clone ( ) , me, 0 , true ) ;
683
+ let group = @taskgroup ( tasks. clone ( ) , me, 0 ) ;
696
684
unsafe { local_set ( me, taskgroup_key, group) ; }
697
- // Tell child task it's also in the main group.
698
- ( tasks, true )
685
+ tasks
699
686
}
700
687
}
701
688
}
702
689
703
690
fn spawn_raw ( opts : task_opts , +f : fn ~( ) ) {
704
691
// Decide whether the child needs to be in a new linked failure group.
705
- let ( child_tg, is_main ) = if opts. supervise {
692
+ let child_tg: taskgroup_arc = if opts. supervise {
706
693
share_parent_taskgroup ( )
707
694
} else {
708
- // Detached from the parent group; create a new (non-main) one.
709
- ( arc:: exclusive ( some ( dvec:: from_elem ( none) ) ) , false )
695
+ arc:: exclusive ( some ( dvec:: from_elem ( none) ) )
710
696
} ;
711
697
712
698
unsafe {
@@ -726,8 +712,7 @@ fn spawn_raw(opts: task_opts, +f: fn~()) {
726
712
// Getting killed after here would leak the task.
727
713
728
714
let child_wrapper =
729
- make_child_wrapper ( new_task, child_tg,
730
- opts. supervise , is_main, f) ;
715
+ make_child_wrapper ( new_task, child_tg, opts. supervise , f) ;
731
716
let fptr = ptr:: addr_of ( child_wrapper) ;
732
717
let closure: * rust_closure = unsafe :: reinterpret_cast ( fptr) ;
733
718
@@ -745,8 +730,7 @@ fn spawn_raw(opts: task_opts, +f: fn~()) {
745
730
}
746
731
747
732
fn make_child_wrapper ( child_task : * rust_task , -child_tg : taskgroup_arc ,
748
- supervise : bool , is_main : bool ,
749
- -f : fn ~( ) ) -> fn ~( ) {
733
+ supervise : bool , -f : fn ~( ) ) -> fn ~( ) {
750
734
let child_tg_ptr = ~mut some ( child_tg) ;
751
735
fn ~( ) {
752
736
// Agh. Get move-mode items into the closure. FIXME (#2829)
@@ -762,12 +746,13 @@ fn spawn_raw(opts: task_opts, +f: fn~()) {
762
746
// parent was already failing, so don't bother doing anything.
763
747
alt enlist_in_taskgroup ( child_tg, child_task) {
764
748
some ( my_index) {
765
- let group =
766
- @taskgroup ( child_tg, child_task, my_index, is_main) ;
749
+ let group = @taskgroup ( child_tg, child_task, my_index) ;
767
750
unsafe { local_set ( child_task, taskgroup_key, group) ; }
768
751
// Run the child's body.
769
752
f ( ) ;
770
- // TLS cleanup code will exit the taskgroup.
753
+ // Report successful exit. (TLS cleanup code will tear
754
+ // down the group.)
755
+ group. failed = false ;
771
756
}
772
757
none { }
773
758
}
@@ -1021,7 +1006,6 @@ extern mod rustrt {
1021
1006
fn rust_task_inhibit_kill ( ) ;
1022
1007
fn rust_task_allow_kill ( ) ;
1023
1008
fn rust_task_kill_other ( task : * rust_task ) ;
1024
- fn rust_task_kill_all ( task : * rust_task ) ;
1025
1009
1026
1010
#[ rust_stack]
1027
1011
fn rust_get_task_local_data ( task : * rust_task ) -> * libc:: c_void ;
0 commit comments