File tree Expand file tree Collapse file tree 3 files changed +45
-3
lines changed Expand file tree Collapse file tree 3 files changed +45
-3
lines changed Original file line number Diff line number Diff line change @@ -14,6 +14,6 @@ refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0
14
14
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
15
15
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
16
16
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
17
- refs/heads/auto: cde6ad39920ddadd7c70921232ae92adff258367
17
+ refs/heads/auto: d30cca46e61f8e5e604a87f0e623cb852be6c85f
18
18
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
19
19
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
Original file line number Diff line number Diff line change @@ -548,11 +548,12 @@ impl Death {
548
548
/// All calls must be paired with a subsequent call to allow_kill.
549
549
#[ inline]
550
550
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 {
552
554
rtassert ! ( self . kill_handle. is_some( ) ) ;
553
555
self . kill_handle . get_mut_ref ( ) . inhibit_kill ( already_failing) ;
554
556
}
555
- self . unkillable += 1 ;
556
557
}
557
558
558
559
/// Exit a possibly-nested unkillable section of code.
Original file line number Diff line number Diff line change @@ -655,6 +655,47 @@ pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {
655
655
}
656
656
}
657
657
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
+
658
699
#[ test] #[ should_fail] #[ ignore( cfg( windows) ) ]
659
700
fn test_cant_dup_task_builder ( ) {
660
701
let mut builder = task ( ) ;
You can’t perform that action at this time.
0 commit comments