72
72
73
73
#[ doc( hidden) ] ; // FIXME #3538
74
74
75
+ use cast:: transmute;
75
76
use cast;
76
77
use cell:: Cell ;
77
78
use container:: Map ;
@@ -117,10 +118,10 @@ pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) {
117
118
struct TaskGroupData {
118
119
// All tasks which might kill this group. When this is empty, the group
119
120
// can be "GC"ed (i.e., its link in the ancestor list can be removed).
120
- mut members : TaskSet ,
121
+ members : TaskSet ,
121
122
// All tasks unidirectionally supervised by (directly or transitively)
122
123
// tasks in this group.
123
- mut descendants : TaskSet ,
124
+ descendants : TaskSet ,
124
125
}
125
126
type TaskGroupArc = unstable:: Exclusive < Option < TaskGroupData > > ;
126
127
@@ -145,11 +146,11 @@ struct AncestorNode {
145
146
// Hence we assert that this counter monotonically decreases as we
146
147
// approach the tail of the list.
147
148
// FIXME(#3068): Make the generation counter togglable with #[cfg(debug)].
148
- generation : uint ,
149
- // Should really be an immutable non-option. This way appeases borrowck.
150
- mut parent_group : Option < TaskGroupArc > ,
149
+ generation : uint ,
150
+ // Should really be a non-option. This way appeases borrowck.
151
+ parent_group : Option < TaskGroupArc > ,
151
152
// Recursive rest of the list.
152
- mut ancestors : AncestorList ,
153
+ ancestors : AncestorList ,
153
154
}
154
155
155
156
struct AncestorList ( Option < unstable:: Exclusive < AncestorNode > > ) ;
@@ -301,22 +302,26 @@ fn each_ancestor(list: &mut AncestorList,
301
302
302
303
// One of these per task.
303
304
struct TCB {
304
- me : * rust_task ,
305
+ me : * rust_task ,
305
306
// List of tasks with whose fates this one's is intertwined.
306
- tasks : TaskGroupArc , // 'none' means the group has failed.
307
+ tasks : TaskGroupArc , // 'none' means the group has failed.
307
308
// Lists of tasks who will kill us if they fail, but whom we won't kill.
308
- mut ancestors : AncestorList ,
309
- is_main : bool ,
310
- notifier : Option < AutoNotify > ,
309
+ ancestors : AncestorList ,
310
+ is_main : bool ,
311
+ notifier : Option < AutoNotify > ,
311
312
}
312
313
313
314
impl Drop for TCB {
314
315
// Runs on task exit.
315
316
fn finalize ( & self ) {
316
317
unsafe {
318
+ let this: & mut TCB = transmute ( self ) ;
319
+
317
320
// If we are failing, the whole taskgroup needs to die.
318
321
if rt:: rust_task_is_unwinding ( self . me ) {
319
- for self . notifier. each |x| { x. failed = true ; }
322
+ for this. notifier. each_mut |x| {
323
+ x. failed = true ;
324
+ }
320
325
// Take everybody down with us.
321
326
do access_group ( & self . tasks ) |tg| {
322
327
kill_taskgroup ( tg, self . me , self . is_main ) ;
@@ -331,16 +336,21 @@ impl Drop for TCB {
331
336
// with our own taskgroup, so long as both happen before we die.
332
337
// We remove ourself from every ancestor we can, so no cleanup; no
333
338
// break.
334
- for each_ancestor( & mut self . ancestors, None ) |ancestor_group| {
339
+ for each_ancestor( & mut this . ancestors, None ) |ancestor_group| {
335
340
leave_taskgroup( ancestor_group, self . me, false ) ;
336
341
} ;
337
342
}
338
343
}
339
344
}
340
345
341
- fn TCB ( me : * rust_task , tasks : TaskGroupArc , ancestors : AncestorList ,
342
- is_main : bool , notifier : Option < AutoNotify > ) -> TCB {
343
- for notifier. each |x| { x. failed = false ; }
346
+ fn TCB ( me : * rust_task ,
347
+ tasks : TaskGroupArc ,
348
+ ancestors : AncestorList ,
349
+ is_main : bool ,
350
+ mut notifier : Option < AutoNotify > ) -> TCB {
351
+ for notifier. each_mut |x| {
352
+ x. failed = false ;
353
+ }
344
354
345
355
TCB {
346
356
me : me,
@@ -353,7 +363,7 @@ fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
353
363
354
364
struct AutoNotify {
355
365
notify_chan : Chan < TaskResult > ,
356
- mut failed : bool ,
366
+ failed : bool ,
357
367
}
358
368
359
369
impl Drop for AutoNotify {
@@ -375,9 +385,12 @@ fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
375
385
let newstate = util:: replace ( & mut * state, None ) ;
376
386
// If 'None', the group was failing. Can't enlist.
377
387
if newstate. is_some ( ) {
378
- let group = newstate. unwrap ( ) ;
379
- taskset_insert ( if is_member { & mut group. members }
380
- else { & mut group. descendants } , me) ;
388
+ let mut group = newstate. unwrap ( ) ;
389
+ taskset_insert ( if is_member {
390
+ & mut group. members
391
+ } else {
392
+ & mut group. descendants
393
+ } , me) ;
381
394
* state = Some ( group) ;
382
395
true
383
396
} else {
@@ -391,9 +404,12 @@ fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
391
404
let newstate = util:: replace ( & mut * state, None ) ;
392
405
// If 'None', already failing and we've already gotten a kill signal.
393
406
if newstate. is_some ( ) {
394
- let group = newstate. unwrap ( ) ;
395
- taskset_remove ( if is_member { & mut group. members }
396
- else { & mut group. descendants } , me) ;
407
+ let mut group = newstate. unwrap ( ) ;
408
+ taskset_remove ( if is_member {
409
+ & mut group. members
410
+ } else {
411
+ & mut group. descendants
412
+ } , me) ;
397
413
* state = Some ( group) ;
398
414
}
399
415
}
@@ -451,23 +467,30 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
451
467
/*##################################################################*
452
468
* Step 1. Get spawner's taskgroup info.
453
469
*##################################################################*/
454
- let spawner_group = match local_get ( OldHandle ( spawner) , taskgroup_key ! ( ) ) {
455
- None => {
456
- // Main task, doing first spawn ever. Lazily initialise here.
457
- let mut members = new_taskset ( ) ;
458
- taskset_insert ( & mut members, spawner) ;
459
- let tasks = unstable:: exclusive ( Some ( TaskGroupData {
460
- members : members,
461
- descendants : new_taskset ( ) ,
462
- } ) ) ;
463
- // Main task/group has no ancestors, no notifier, etc.
464
- let group =
465
- @TCB ( spawner, tasks, AncestorList ( None ) , true , None ) ;
466
- local_set ( OldHandle ( spawner) , taskgroup_key ! ( ) , group) ;
467
- group
468
- }
469
- Some ( group) => group
470
- } ;
470
+ let mut spawner_group: @@mut TCB =
471
+ match local_get ( OldHandle ( spawner) , taskgroup_key ! ( ) ) {
472
+ None => {
473
+ // Main task, doing first spawn ever. Lazily initialise
474
+ // here.
475
+ let mut members = new_taskset ( ) ;
476
+ taskset_insert ( & mut members, spawner) ;
477
+ let tasks = unstable:: exclusive ( Some ( TaskGroupData {
478
+ members : members,
479
+ descendants : new_taskset ( ) ,
480
+ } ) ) ;
481
+ // Main task/group has no ancestors, no notifier, etc.
482
+ let group = @@mut TCB ( spawner,
483
+ tasks,
484
+ AncestorList ( None ) ,
485
+ true ,
486
+ None ) ;
487
+ local_set ( OldHandle ( spawner) , taskgroup_key ! ( ) , group) ;
488
+ group
489
+ }
490
+ Some ( group) => group
491
+ } ;
492
+ let spawner_group: & mut TCB = * spawner_group;
493
+
471
494
/*##################################################################*
472
495
* Step 2. Process spawn options for child.
473
496
*##################################################################*/
@@ -624,8 +647,11 @@ fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) {
624
647
};
625
648
626
649
if enlist_many(child, &child_arc, &mut ancestors) {
627
- let group = @TCB(child, child_arc, ancestors,
628
- is_main, notifier);
650
+ let group = @@mut TCB(child,
651
+ child_arc,
652
+ ancestors,
653
+ is_main,
654
+ notifier);
629
655
unsafe {
630
656
local_set(OldHandle(child), taskgroup_key!(), group);
631
657
}
0 commit comments