@@ -464,6 +464,7 @@ impl Drop for Death {
464
464
#[ cfg( test) ]
465
465
mod test {
466
466
#[ allow( unused_mut) ] ;
467
+ use cell:: Cell ;
467
468
use rt:: test:: * ;
468
469
use super :: * ;
469
470
use util;
@@ -599,4 +600,143 @@ mod test {
599
600
assert ! ( parent_inner. any_child_failed == false ) ;
600
601
}
601
602
}
603
+
604
+ // Task killing tests
605
+
606
+ #[ test]
607
+ fn kill_basic ( ) {
608
+ do run_in_newsched_task {
609
+ let mut handle = KillHandle :: new ( ) ;
610
+ assert ! ( !handle. killed( ) ) ;
611
+ assert ! ( handle. kill( ) . is_none( ) ) ;
612
+ assert ! ( handle. killed( ) ) ;
613
+ }
614
+ }
615
+
616
+ #[ test]
617
+ fn double_kill ( ) {
618
+ do run_in_newsched_task {
619
+ let mut handle = KillHandle :: new ( ) ;
620
+ assert ! ( !handle. killed( ) ) ;
621
+ assert ! ( handle. kill( ) . is_none( ) ) ;
622
+ assert ! ( handle. killed( ) ) ;
623
+ assert ! ( handle. kill( ) . is_none( ) ) ;
624
+ assert ! ( handle. killed( ) ) ;
625
+ }
626
+ }
627
+
628
+ #[ test]
629
+ fn unkillable_after_kill ( ) {
630
+ do run_in_newsched_task {
631
+ let mut handle = KillHandle :: new ( ) ;
632
+ assert ! ( handle. kill( ) . is_none( ) ) ;
633
+ assert ! ( handle. killed( ) ) ;
634
+ let handle_cell = Cell :: new ( handle) ;
635
+ let result = do spawntask_try {
636
+ handle_cell. take ( ) . inhibit_kill ( false ) ;
637
+ } ;
638
+ assert ! ( result. is_err( ) ) ;
639
+ }
640
+ }
641
+
642
+ #[ test]
643
+ fn unkillable_during_kill ( ) {
644
+ do run_in_newsched_task {
645
+ let mut handle = KillHandle :: new ( ) ;
646
+ handle. inhibit_kill ( false ) ;
647
+ assert ! ( handle. kill( ) . is_none( ) ) ;
648
+ assert ! ( !handle. killed( ) ) ;
649
+ let handle_cell = Cell :: new ( handle) ;
650
+ let result = do spawntask_try {
651
+ handle_cell. take ( ) . allow_kill ( false ) ;
652
+ } ;
653
+ assert ! ( result. is_err( ) ) ;
654
+ }
655
+ }
656
+
657
+ #[ test]
658
+ fn unkillable_before_kill ( ) {
659
+ do run_in_newsched_task {
660
+ let mut handle = KillHandle :: new ( ) ;
661
+ handle. inhibit_kill ( false ) ;
662
+ handle. allow_kill ( false ) ;
663
+ assert ! ( handle. kill( ) . is_none( ) ) ;
664
+ assert ! ( handle. killed( ) ) ;
665
+ }
666
+ }
667
+
668
+ // Task blocking tests
669
+
670
+ #[ test]
671
+ fn block_and_wake ( ) {
672
+ do with_test_task |mut task| {
673
+ BlockedTask :: try_block ( task) . unwrap_right ( ) . wake ( ) . unwrap ( )
674
+ }
675
+ }
676
+
677
+ #[ test]
678
+ fn block_and_get_killed ( ) {
679
+ do with_test_task |mut task| {
680
+ let mut handle = task. death . kill_handle . get_ref ( ) . clone ( ) ;
681
+ let result = BlockedTask :: try_block ( task) . unwrap_right ( ) ;
682
+ let task = handle. kill ( ) . unwrap ( ) ;
683
+ assert ! ( result. wake( ) . is_none( ) ) ;
684
+ task
685
+ }
686
+ }
687
+
688
+ #[ test]
689
+ fn block_already_killed ( ) {
690
+ do with_test_task |mut task| {
691
+ let mut handle = task. death . kill_handle . get_ref ( ) . clone ( ) ;
692
+ assert ! ( handle. kill( ) . is_none( ) ) ;
693
+ BlockedTask :: try_block ( task) . unwrap_left ( )
694
+ }
695
+ }
696
+
697
+ #[ test]
698
+ fn block_unkillably_and_get_killed ( ) {
699
+ do with_test_task |mut task| {
700
+ let mut handle = task. death . kill_handle . get_ref ( ) . clone ( ) ;
701
+ task. death . inhibit_kill ( false ) ;
702
+ let result = BlockedTask :: try_block ( task) . unwrap_right ( ) ;
703
+ assert ! ( handle. kill( ) . is_none( ) ) ;
704
+ let mut task = result. wake ( ) . unwrap ( ) ;
705
+ // This call wants to fail, but we can't have that happen since
706
+ // we're not running in a newsched task, so we can't even use
707
+ // spawntask_try. But the failing behaviour is already tested
708
+ // above, in unkillable_during_kill(), so we punt on it here.
709
+ task. death . allow_kill ( true ) ;
710
+ task
711
+ }
712
+ }
713
+
714
+ #[ test]
715
+ fn block_on_pipe ( ) {
716
+ // Tests the "killable" path of casting to/from uint.
717
+ do run_in_newsched_task {
718
+ do with_test_task |mut task | {
719
+ let result = BlockedTask :: try_block ( task) . unwrap_right ( ) ;
720
+ let result = unsafe { result. cast_to_uint ( ) } ;
721
+ let result = unsafe { BlockedTask :: cast_from_uint ( result) } ;
722
+ result. wake ( ) . unwrap ( )
723
+ }
724
+ }
725
+ }
726
+
727
+ #[ test]
728
+ fn block_unkillably_on_pipe ( ) {
729
+ // Tests the "indestructible" path of casting to/from uint.
730
+ do run_in_newsched_task {
731
+ do with_test_task |mut task | {
732
+ task. death . inhibit_kill ( false ) ;
733
+ let result = BlockedTask :: try_block ( task) . unwrap_right ( ) ;
734
+ let result = unsafe { result. cast_to_uint ( ) } ;
735
+ let result = unsafe { BlockedTask :: cast_from_uint ( result) } ;
736
+ let mut task = result. wake ( ) . unwrap ( ) ;
737
+ task. death . allow_kill ( false ) ;
738
+ task
739
+ }
740
+ }
741
+ }
602
742
}
0 commit comments