@@ -178,8 +178,8 @@ struct AncestorNode {
178
178
// approach the tail of the list.
179
179
// FIXME(#3068): Make the generation counter togglable with #[cfg(debug)].
180
180
generation : uint ,
181
- // Should really be a non-option. This way appeases borrowck .
182
- parent_group : Option < TaskGroupArc > ,
181
+ // Handle to the tasks in the group of the current generation .
182
+ parent_group : TaskGroupArc ,
183
183
// Recursive rest of the list.
184
184
ancestors : AncestorList ,
185
185
}
@@ -221,18 +221,13 @@ fn each_ancestor(list: &mut AncestorList,
221
221
bail_blk : & fn ( TaskGroupInner ) ,
222
222
forward_blk : & fn ( TaskGroupInner ) -> bool ,
223
223
last_generation : uint ) -> bool {
224
- // Need to swap the list out to use it, to appease borrowck.
225
- let tmp_list = util:: replace ( & mut * list, AncestorList ( None ) ) ;
226
224
let ( coalesce_this, early_break) =
227
- iterate ( & tmp_list , bail_blk, forward_blk, last_generation) ;
225
+ iterate ( list , bail_blk, forward_blk, last_generation) ;
228
226
// What should our next ancestor end up being?
229
227
if coalesce_this. is_some ( ) {
230
228
// Needed coalesce. Our next ancestor becomes our old
231
229
// ancestor's next ancestor. ("next = old_next->next;")
232
230
* list = coalesce_this. unwrap ( ) ;
233
- } else {
234
- // No coalesce; restore from tmp. ("next = old_next;")
235
- * list = tmp_list;
236
231
}
237
232
return early_break;
238
233
}
@@ -245,7 +240,7 @@ fn each_ancestor(list: &mut AncestorList,
245
240
// bool:
246
241
// True if the supplied block did 'break', here or in any recursive
247
242
// calls. If so, must call the unwinder on all previous nodes.
248
- fn iterate ( ancestors : & AncestorList ,
243
+ fn iterate ( ancestors : & mut AncestorList ,
249
244
bail_blk : & fn ( TaskGroupInner ) ,
250
245
forward_blk : & fn ( TaskGroupInner ) -> bool ,
251
246
last_generation : uint )
@@ -263,7 +258,7 @@ fn each_ancestor(list: &mut AncestorList,
263
258
264
259
// The map defaults to None, because if ancestors is None, we're at
265
260
// the end of the list, which doesn't make sense to coalesce.
266
- return do ( * * ancestors) . map_default ( ( None , false ) ) |ancestor_arc| {
261
+ do ancestors. map_default ( ( None , false ) ) |ancestor_arc| {
267
262
// NB: Takes a lock! (this ancestor node)
268
263
do access_ancestors ( ancestor_arc) |nobe| {
269
264
// Argh, but we couldn't give it to coalesce() otherwise.
@@ -276,7 +271,7 @@ fn each_ancestor(list: &mut AncestorList,
276
271
let mut nobe_is_dead = false ;
277
272
let do_continue =
278
273
// NB: Takes a lock! (this ancestor node's parent group)
279
- do with_parent_tg ( & mut nobe. parent_group ) |tg_opt| {
274
+ do access_group ( & nobe. parent_group ) |tg_opt| {
280
275
// Decide whether this group is dead. Note that the
281
276
// group being *dead* is disjoint from it *failing*.
282
277
nobe_is_dead = match * tg_opt {
@@ -305,7 +300,7 @@ fn each_ancestor(list: &mut AncestorList,
305
300
* Step 3: Maybe unwind; compute return info for our caller.
306
301
*##########################################################*/
307
302
if need_unwind && !nobe_is_dead {
308
- do with_parent_tg ( & mut nobe. parent_group ) |tg_opt| {
303
+ do access_group ( & nobe. parent_group ) |tg_opt| {
309
304
bail_blk ( tg_opt)
310
305
}
311
306
}
@@ -321,16 +316,6 @@ fn each_ancestor(list: &mut AncestorList,
321
316
( None , need_unwind)
322
317
}
323
318
}
324
- } ;
325
-
326
- // Wrapper around exclusive::with that appeases borrowck.
327
- fn with_parent_tg < U > ( parent_group : & mut Option < TaskGroupArc > ,
328
- blk : & fn ( TaskGroupInner ) -> U ) -> U {
329
- // If this trips, more likely the problem is 'blk' failed inside.
330
- let tmp_arc = parent_group. take_unwrap ( ) ;
331
- let result = do access_group ( & tmp_arc) |tg_opt| { blk ( tg_opt) } ;
332
- * parent_group = Some ( tmp_arc) ;
333
- result
334
319
}
335
320
}
336
321
}
@@ -544,7 +529,7 @@ impl RuntimeGlue {
544
529
}
545
530
}
546
531
547
- fn with_my_taskgroup < U > ( blk : & fn ( & mut TCB ) -> U ) -> U {
532
+ fn with_my_taskgroup < U > ( blk : & fn ( & TCB ) -> U ) -> U {
548
533
match context ( ) {
549
534
OldTaskContext => unsafe {
550
535
let me = rt:: rust_get_task ( ) ;
@@ -561,9 +546,9 @@ impl RuntimeGlue {
561
546
// Main task/group has no ancestors, no notifier, etc.
562
547
let group = @@mut TCB ( tasks, AncestorList ( None ) , true , None ) ;
563
548
local_set ( OldHandle ( me) , taskgroup_key ( ) , group) ;
564
- blk ( & mut * * group)
549
+ blk ( & * * group)
565
550
}
566
- Some ( & group) => blk ( & mut * * group)
551
+ Some ( & group) => blk ( & * * group)
567
552
}
568
553
}
569
554
} ,
@@ -583,9 +568,9 @@ impl RuntimeGlue {
583
568
} ) ) ;
584
569
let group = TCB ( tasks, AncestorList ( None ) , true , None ) ;
585
570
( * me) . taskgroup = Some ( group) ;
586
- ( * me) . taskgroup . get_mut_ref ( )
571
+ ( * me) . taskgroup . get_ref ( )
587
572
}
588
- Some ( ref mut group) => group,
573
+ Some ( ref group) => group,
589
574
} )
590
575
} ,
591
576
SchedulerContext | GlobalContext => rtabort ! ( "spawning in bad context" ) ,
@@ -595,64 +580,44 @@ impl RuntimeGlue {
595
580
596
581
fn gen_child_taskgroup ( linked : bool , supervised : bool )
597
582
-> ( TaskGroupArc , AncestorList , bool ) {
598
- return do RuntimeGlue :: with_my_taskgroup |spawner_group| {
583
+ do RuntimeGlue :: with_my_taskgroup |spawner_group| {
584
+ let ancestors = AncestorList ( spawner_group. ancestors . map ( |x| x. clone ( ) ) ) ;
599
585
if linked {
600
586
// Child is in the same group as spawner.
601
- let g = spawner_group. tasks . clone ( ) ;
602
587
// Child's ancestors are spawner's ancestors.
603
- let a = share_ancestors ( & mut spawner_group. ancestors ) ;
604
588
// Propagate main-ness.
605
- ( g , a , spawner_group. is_main )
589
+ ( spawner_group . tasks . clone ( ) , ancestors , spawner_group. is_main )
606
590
} else {
607
591
// Child is in a separate group from spawner.
608
592
let g = exclusive ( Some ( TaskGroupData {
609
593
members : new_taskset ( ) ,
610
594
descendants : new_taskset ( ) ,
611
595
} ) ) ;
612
596
let a = if supervised {
613
- // Child's ancestors start with the spawner.
614
- let old_ancestors =
615
- share_ancestors ( & mut spawner_group. ancestors ) ;
616
597
// FIXME(#3068) - The generation counter is only used for a
617
598
// debug assertion, but initialising it requires locking a
618
599
// mutex. Hence it should be enabled only in debug builds.
619
600
let new_generation =
620
- match * old_ancestors {
601
+ match * ancestors {
621
602
Some ( ref arc) => {
622
603
access_ancestors ( arc, |a| a. generation +1 )
623
604
}
624
605
None => 0 // the actual value doesn't really matter.
625
606
} ;
626
607
assert ! ( new_generation < uint:: max_value) ;
608
+ // Child's ancestors start with the spawner.
627
609
// Build a new node in the ancestor list.
628
610
AncestorList ( Some ( exclusive ( AncestorNode {
629
611
generation : new_generation,
630
- parent_group : Some ( spawner_group. tasks . clone ( ) ) ,
631
- ancestors : old_ancestors ,
612
+ parent_group : spawner_group. tasks . clone ( ) ,
613
+ ancestors : ancestors ,
632
614
} ) ) )
633
615
} else {
634
616
// Child has no ancestors.
635
617
AncestorList ( None )
636
618
} ;
637
619
( g, a, false )
638
620
}
639
- } ;
640
-
641
- fn share_ancestors ( ancestors : & mut AncestorList ) -> AncestorList {
642
- // Appease the borrow-checker. Really this wants to be written as:
643
- // match ancestors
644
- // Some(ancestor_arc) { ancestor_list(Some(ancestor_arc.clone())) }
645
- // None { ancestor_list(None) }
646
- let tmp = util:: replace ( & mut * * ancestors, None ) ;
647
- if tmp. is_some ( ) {
648
- let ancestor_arc = tmp. unwrap ( ) ;
649
- let result = ancestor_arc. clone ( ) ;
650
- error ! ( "cloned ancestors" ) ;
651
- * * ancestors = Some ( ancestor_arc) ;
652
- AncestorList ( Some ( result) )
653
- } else {
654
- AncestorList ( None )
655
- }
656
621
}
657
622
}
658
623
@@ -754,14 +719,8 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
754
719
} ;
755
720
assert ! ( !new_task. is_null( ) ) ;
756
721
// Getting killed after here would leak the task.
757
- let notify_chan = if opts. notify_chan . is_none ( ) {
758
- None
759
- } else {
760
- Some ( opts. notify_chan . take_unwrap ( ) )
761
- } ;
762
-
763
722
let child_wrapper = make_child_wrapper ( new_task, child_tg,
764
- ancestors, is_main, notify_chan, f) ;
723
+ ancestors, is_main, opts . notify_chan . take ( ) , f) ;
765
724
766
725
let closure = cast:: transmute ( & child_wrapper) ;
767
726
0 commit comments