use option::{Option, Some, None};
use prelude::*;
use rt::task::Task;
+use task::spawn::Taskgroup;
use to_bytes::IterBytes;
use unstable::atomics::{AtomicUint, Relaxed};
use unstable::sync::{UnsafeAtomicRcBox, LittleLock};
}
/// Collect failure exit codes from children and propagate them to a parent.
- pub fn collect_failure(&mut self, mut success: bool) {
+ pub fn collect_failure(&mut self, mut success: bool, group: Option<Taskgroup>) {
// This may run after the task has already failed, so even though the
// task appears to need to be killed, the scheduler should not fail us
// when we block to unwrap.
rtassert!(self.unkillable == 0);
self.unkillable = 1;
+ // FIXME(#7544): See corresponding fixme at the callsite in task.rs.
+ // NB(#8192): Doesn't work with "let _ = ..."
+ { use util; util::ignore(group); }
+
// Step 1. Decide if we need to collect child failures synchronously.
do self.on_exit.take_map |on_exit| {
if success {
}
self.unwinder.try(f);
- { let _ = self.taskgroup.take(); }
- self.death.collect_failure(!self.unwinder.unwinding);
+ // FIXME(#7544): We pass the taskgroup into death so that it can be
+ // dropped while the unkillable counter is set. This should not be
+ // necessary except for an extraneous clone() in task/spawn.rs that
+ // causes a killhandle to get dropped, which mustn't receive a kill
+ // signal since we're outside of the unwinder's try() scope.
+ // { let _ = self.taskgroup.take(); }
+ self.death.collect_failure(!self.unwinder.unwinding, self.taskgroup.take());
self.destroy();
}