From 963d37e821590b470f7a1fc9cfcda5a5ceceeee4 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Wed, 31 Jul 2013 19:48:38 -0400 Subject: [PATCH] Temporary workaround to prevent taskgroup cleanup code from failing without an exception handler. --- src/libstd/rt/kill.rs | 7 ++++++- src/libstd/rt/task.rs | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/libstd/rt/kill.rs b/src/libstd/rt/kill.rs index 208af522d80..696f4a8c355 100644 --- a/src/libstd/rt/kill.rs +++ b/src/libstd/rt/kill.rs @@ -72,6 +72,7 @@ use either::{Either, Left, Right}; 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}; @@ -474,7 +475,7 @@ impl Death { } /// 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) { // 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. @@ -484,6 +485,10 @@ impl Death { 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 { diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index c1b799796d1..f7f1b10e58c 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -129,8 +129,13 @@ impl Task { } 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(); }