::rt::util::abort(format!($($msg)*));
} )
)
-
-macro_rules! assert_once_ever(
- ($($msg:tt)+) => ( {
- // 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 {
- fail2!("assert_once_ever happened twice: {}",
- format!($($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);
- }
-}
use rt::thread::Thread;
use rt::work_queue::WorkQueue;
use rt::uv::uvio::UvEventLoop;
-use unstable::atomics::{AtomicInt, SeqCst};
+use unstable::atomics::{AtomicInt, AtomicBool, SeqCst};
use unstable::sync::UnsafeArc;
use vec;
use vec::{OwnedVector, MutableVector, ImmutableVector};
let exit_code = UnsafeArc::new(AtomicInt::new(0));
let exit_code_clone = exit_code.clone();
+ // Used to sanity check that the runtime only exits once
+ let exited_already = UnsafeArc::new(AtomicBool::new(false));
+
// When the main task exits, after all the tasks in the main
// 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");
+ unsafe {
+ assert!(!(*exited_already.get()).swap(true, SeqCst),
+ "the runtime already exited");
+ }
let mut handles = handles.take();
for handle in handles.mut_iter() {
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-fast windows uses a different test runner
+
+use std::rt;
+
+#[start]
+fn start(argc: int, argv: **u8) -> int {
+ do rt::start(argc, argv) {
+ println("First invocation");
+ };
+
+ do rt::start(argc, argv) {
+ println("Second invocation");
+ };
+
+ 0
+}