File tree Expand file tree Collapse file tree 2 files changed +44
-2
lines changed Expand file tree Collapse file tree 2 files changed +44
-2
lines changed 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