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 1
1
---
2
- refs/heads/master: cde6ad39920ddadd7c70921232ae92adff258367
2
+ refs/heads/master: d30cca46e61f8e5e604a87f0e623cb852be6c85f
3
3
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4
4
refs/heads/snap-stage3: 18e3db7392d2d0697b7e27d6d986139960144d85
5
5
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
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