Skip to content

Commit caa86c9

Browse files
committed
---
yaml --- r: 64982 b: refs/heads/snap-stage3 c: d30cca4 h: refs/heads/master v: v3
1 parent 04ee592 commit caa86c9

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,7 +1,7 @@
11
---
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: cde6ad39920ddadd7c70921232ae92adff258367
4+
refs/heads/snap-stage3: d30cca46e61f8e5e604a87f0e623cb852be6c85f
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/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.

branches/snap-stage3/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)