Add assert_once_ever macro. Close #7748. (fixme cf #8472)

This commit is contained in:
Ben Blum 2013-08-08 19:59:08 -04:00
parent 7f26812895
commit dd406365e1
2 changed files with 37 additions and 0 deletions

View File

@ -40,3 +40,39 @@ macro_rules! rtabort(
} )
)
macro_rules! assert_once_ever(
($( $msg:expr),+) => ( {
// FIXME(#8472) extra function should not be needed to hide unsafe
fn assert_once_ever() {
unsafe {
static mut already_happened: int = 0;
// Double-check lock to avoid a swap in the common case.
if already_happened != 0 ||
::unstable::intrinsics::atomic_xchg_relaxed(&mut already_happened, 1) != 0 {
fail!(fmt!("assert_once_ever happened twice: %s", fmt!($($msg),+)));
}
}
}
assert_once_ever();
} )
)
#[cfg(test)]
mod tests {
#[test]
fn test_assert_once_ever_ok() {
assert_once_ever!("help i'm stuck in an");
assert_once_ever!("assertion error message");
}
#[test] #[ignore(cfg(windows))] #[should_fail]
fn test_assert_once_ever_fail() {
use task;
fn f() { assert_once_ever!("if you're seeing this... good!") }
// linked & watched, naturally
task::spawn(f);
task::spawn(f);
}
}

View File

@ -323,6 +323,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
// task tree, shut down the schedulers and set the exit code.
let handles = Cell::new(handles);
let on_exit: ~fn(bool) = |exit_success| {
assert_once_ever!("last task exiting");
let mut handles = handles.take();
for handle in handles.mut_iter() {