Skip to content

Commit 63f253e

Browse files
committed
---
yaml --- r: 67563 b: refs/heads/master c: d30cca4 h: refs/heads/master i: 67561: c64e526 67559: 42bac1e v: v3
1 parent 8bde1d9 commit 63f253e

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: cde6ad39920ddadd7c70921232ae92adff258367
2+
refs/heads/master: d30cca46e61f8e5e604a87f0e623cb852be6c85f
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 18e3db7392d2d0697b7e27d6d986139960144d85
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9

trunk/src/libstd/rt/kill.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,11 +548,12 @@ impl Death {
548548
/// All calls must be paired with a subsequent call to allow_kill.
549549
#[inline]
550550
pub fn inhibit_kill(&mut self, already_failing: bool) {
551-
if self.unkillable == 0 {
551+
self.unkillable += 1;
552+
// May fail, hence must happen *after* incrementing the counter
553+
if self.unkillable == 1 {
552554
rtassert!(self.kill_handle.is_some());
553555
self.kill_handle.get_mut_ref().inhibit_kill(already_failing);
554556
}
555-
self.unkillable += 1;
556557
}
557558

558559
/// Exit a possibly-nested unkillable section of code.

trunk/src/libstd/task/mod.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,47 @@ pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {
655655
}
656656
}
657657

658+
#[test] #[ignore(cfg(windows))]
659+
fn test_kill_unkillable_task() {
660+
use rt::test::*;
661+
662+
// Attempt to test that when a kill signal is received at the start of an
663+
// unkillable section, 'unkillable' unwinds correctly. This is actually
664+
// quite a difficult race to expose, as the kill has to happen on a second
665+
// CPU, *after* the spawner is already switched-back-to (and passes the
666+
// killed check at the start of its timeslice). As far as I know, it's not
667+
// possible to make this race deterministic, or even more likely to happen.
668+
do run_in_newsched_task {
669+
do task::try {
670+
do task::spawn {
671+
fail!();
672+
}
673+
do task::unkillable { }
674+
};
675+
}
676+
}
677+
678+
#[test] #[ignore(cfg(windows))]
679+
fn test_kill_rekillable_task() {
680+
use rt::test::*;
681+
682+
// Tests that when a kill signal is received, 'rekillable' and
683+
// 'unkillable' unwind correctly in conjunction with each other.
684+
do run_in_newsched_task {
685+
do task::try {
686+
do task::unkillable {
687+
unsafe {
688+
do task::rekillable {
689+
do task::spawn {
690+
fail!();
691+
}
692+
}
693+
}
694+
}
695+
};
696+
}
697+
}
698+
658699
#[test] #[should_fail] #[ignore(cfg(windows))]
659700
fn test_cant_dup_task_builder() {
660701
let mut builder = task();

0 commit comments

Comments
 (0)