diff options
| author | bors <bors@rust-lang.org> | 2013-08-02 14:55:54 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-08-02 14:55:54 -0700 |
| commit | 3ddc72f69be4d0a2027ff598ad262ea2b2ca3812 (patch) | |
| tree | 5942120bc4dba4d4b2da56457b425145030daf29 /src/libstd/rt/kill.rs | |
| parent | f1c1f92d0c555d6e38ad1cac55926d6d9c9b090f (diff) | |
| parent | 43fecf3556b47305320221586f48f89fe2f6c505 (diff) | |
| download | rust-3ddc72f69be4d0a2027ff598ad262ea2b2ca3812.tar.gz rust-3ddc72f69be4d0a2027ff598ad262ea2b2ca3812.zip | |
auto merge of #8234 : bblum/rust/assorted-fixes, r=brson
This fixes 4 bugs that prevented the extra::arc and extra::sync tests from passing on the new runtime. * In ```Add SendDeferred trait``` I add a non-rescheduling ```send_deferred``` method to our various channel types. The ```extra::sync``` concurrency primitives need this guarantee so they can send while inside of an exclusive. (This fixes deterministic deadlocks seen with ```RUST_THREADS=1```.) * In "Fix nasty double-free bug" I make sure that a ```ChanOne``` suppresses_finalize *before* rescheduling away to the receiver, so in case it gets a kill signal upon coming back, the destructor is inhibited as desired. (This is pretty uncommon on multiple CPUs but showed up always with ```RUST_THREADS=1```.) * In ```Fix embarrassing bug where 'unkillable' would unwind improperly``` I make sure the task's unkillable counter stays consistent when a kill signal is received right at the start of an unkillable section. (This is a very uncommon race and can only occur with multiple CPUs.) * In ```Don't fail from kill signals if already unwinding``` I do pretty much what it says on the tin. Surprising that it took the whole suite of sync/arc tests to expose this. The other two commits are cleanup. r @brson
Diffstat (limited to 'src/libstd/rt/kill.rs')
| -rw-r--r-- | src/libstd/rt/kill.rs | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/src/libstd/rt/kill.rs b/src/libstd/rt/kill.rs index 696f4a8c355..deec8dd37a6 100644 --- a/src/libstd/rt/kill.rs +++ b/src/libstd/rt/kill.rs @@ -530,13 +530,13 @@ impl Death { /// Fails if a kill signal was received. #[inline] - pub fn check_killed(&self) { + pub fn check_killed(&self, already_failing: bool) { match self.kill_handle { Some(ref kill_handle) => // The task may be both unkillable and killed if it does some // synchronization during unwinding or cleanup (for example, // sending on a notify port). In that case failing won't help. - if self.unkillable == 0 && kill_handle.killed() { + if self.unkillable == 0 && (!already_failing) && kill_handle.killed() { fail!(KILLED_MSG); }, // This may happen during task death (see comments in collect_failure). @@ -548,11 +548,12 @@ impl Death { /// All calls must be paired with a subsequent call to allow_kill. #[inline] pub fn inhibit_kill(&mut self, already_failing: bool) { - if self.unkillable == 0 { + self.unkillable += 1; + // May fail, hence must happen *after* incrementing the counter + if self.unkillable == 1 { rtassert!(self.kill_handle.is_some()); self.kill_handle.get_mut_ref().inhibit_kill(already_failing); } - self.unkillable += 1; } /// Exit a possibly-nested unkillable section of code. |
