Skip to content

Commit e283c4d

Browse files
committed
Add tests for task killing and blocking.
1 parent a093b54 commit e283c4d

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

src/libstd/rt/kill.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ impl Drop for Death {
464464
#[cfg(test)]
465465
mod test {
466466
#[allow(unused_mut)];
467+
use cell::Cell;
467468
use rt::test::*;
468469
use super::*;
469470
use util;
@@ -599,4 +600,143 @@ mod test {
599600
assert!(parent_inner.any_child_failed == false);
600601
}
601602
}
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+
}
602742
}

0 commit comments

Comments
 (0)