about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/compiletest/compiletest.rs5
-rw-r--r--src/driver/driver.rs8
-rw-r--r--src/libgreen/lib.rs2
-rw-r--r--src/libnative/lib.rs18
-rw-r--r--src/librustc/front/std_inject.rs18
-rw-r--r--src/librustc/middle/lint.rs2
-rw-r--r--src/librustuv/lib.rs11
-rw-r--r--src/libstd/lib.rs10
-rw-r--r--src/test/run-fail/native-failure.rs2
-rw-r--r--src/test/run-make/bootstrap-from-c-with-green/lib.rs1
-rw-r--r--src/test/run-make/bootstrap-from-c-with-native/lib.rs1
-rw-r--r--src/test/run-pass/capturing-logging.rs3
-rw-r--r--src/test/run-pass/core-run-destroy.rs125
-rw-r--r--src/test/run-pass/native-print-no-runtime.rs2
-rw-r--r--src/test/run-pass/process-detach.rs6
15 files changed, 130 insertions, 84 deletions
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index da21db6e5d5..e86309f81af 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -19,6 +19,8 @@ extern crate test;
 extern crate getopts;
 #[phase(link, syntax)]
 extern crate log;
+extern crate green;
+extern crate rustuv;
 
 use std::os;
 use std::io;
@@ -41,6 +43,9 @@ pub mod runtest;
 pub mod common;
 pub mod errors;
 
+#[start]
+fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
+
 pub fn main() {
     let args = os::args();
     let config = parse_config(args.move_iter().collect());
diff --git a/src/driver/driver.rs b/src/driver/driver.rs
index 0ceb12064b0..bd7096cda03 100644
--- a/src/driver/driver.rs
+++ b/src/driver/driver.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[no_uv];
+#[no_uv]; // remove this after stage0
+#[allow(attribute_usage)]; // remove this after stage0
+extern crate native; // remove this after stage0
 
 #[cfg(rustdoc)]
 extern crate this = "rustdoc";
@@ -16,7 +18,9 @@ extern crate this = "rustdoc";
 #[cfg(rustc)]
 extern crate this = "rustc";
 
-extern crate native;
+#[cfg(not(stage0))]
+fn main() { this::main() }
 
+#[cfg(stage0)]
 #[start]
 fn start(argc: int, argv: **u8) -> int { native::start(argc, argv, this::main) }
diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs
index b9846c9c3a2..926b9028a7a 100644
--- a/src/libgreen/lib.rs
+++ b/src/libgreen/lib.rs
@@ -209,7 +209,7 @@ pub mod stack;
 pub mod task;
 
 #[lang = "start"]
-#[cfg(not(test))]
+#[cfg(not(test), stage0)]
 pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
     use std::cast;
     start(argc, argv, proc() {
diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs
index f50cf727864..afe440cc1e0 100644
--- a/src/libnative/lib.rs
+++ b/src/libnative/lib.rs
@@ -58,6 +58,7 @@
 
 use std::os;
 use std::rt;
+use std::str;
 
 pub mod io;
 pub mod task;
@@ -68,6 +69,16 @@ static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
 #[cfg(unix, not(android))]
 static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
 
+#[lang = "start"]
+#[cfg(not(test), not(stage0))]
+pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
+    use std::cast;
+    start(argc, argv, proc() {
+        let main: extern "Rust" fn() = unsafe { cast::transmute(main) };
+        main();
+    })
+}
+
 /// Executes the given procedure after initializing the runtime with the given
 /// argc/argv.
 ///
@@ -90,7 +101,12 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
     rt::init(argc, argv);
     let mut exit_code = None;
     let mut main = Some(main);
-    let t = task::new((my_stack_bottom, my_stack_top)).run(|| {
+    let mut task = task::new((my_stack_bottom, my_stack_top));
+    task.name = Some(str::Slice("<main>"));
+    let t = task.run(|| {
+        unsafe {
+            rt::stack::record_stack_bounds(my_stack_bottom, my_stack_top);
+        }
         exit_code = Some(run(main.take_unwrap()));
     });
     drop(t);
diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs
index 6a6819ae516..a78f90cbe87 100644
--- a/src/librustc/front/std_inject.rs
+++ b/src/librustc/front/std_inject.rs
@@ -46,8 +46,8 @@ fn use_std(krate: &ast::Crate) -> bool {
     !attr::contains_name(krate.attrs.as_slice(), "no_std")
 }
 
-fn use_uv(krate: &ast::Crate) -> bool {
-    !attr::contains_name(krate.attrs.as_slice(), "no_uv")
+fn use_start(krate: &ast::Crate) -> bool {
+    !attr::contains_name(krate.attrs.as_slice(), "no_start")
 }
 
 fn no_prelude(attrs: &[ast::Attribute]) -> bool {
@@ -87,18 +87,10 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
             span: DUMMY_SP
         });
 
-        if use_uv(&krate) && !self.sess.building_library.get() {
+        if use_start(&krate) && !self.sess.building_library.get() {
             vis.push(ast::ViewItem {
-                node: ast::ViewItemExternCrate(token::str_to_ident("green"),
-                                             with_version("green"),
-                                             ast::DUMMY_NODE_ID),
-                attrs: Vec::new(),
-                vis: ast::Inherited,
-                span: DUMMY_SP
-            });
-            vis.push(ast::ViewItem {
-                node: ast::ViewItemExternCrate(token::str_to_ident("rustuv"),
-                                             with_version("rustuv"),
+                node: ast::ViewItemExternCrate(token::str_to_ident("native"),
+                                             with_version("native"),
                                              ast::DUMMY_NODE_ID),
                 attrs: Vec::new(),
                 vis: ast::Inherited,
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 6c13d496166..286ecbd6c8f 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -961,7 +961,7 @@ fn check_heap_item(cx: &Context, it: &ast::Item) {
 }
 
 static crate_attrs: &'static [&'static str] = &[
-    "crate_type", "feature", "no_uv", "no_main", "no_std", "crate_id",
+    "crate_type", "feature", "no_start", "no_main", "no_std", "crate_id",
     "desc", "comment", "license", "copyright", // not used in rustc now
 ];
 
diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs
index ee4f15e7954..42ccdaf9562 100644
--- a/src/librustuv/lib.rs
+++ b/src/librustuv/lib.rs
@@ -45,6 +45,7 @@ via `close` and `delete` methods.
 #[allow(deprecated_owned_vector)]; // NOTE: remove after stage0
 
 #[cfg(test)] extern crate green;
+#[cfg(test)] extern crate realrustuv = "rustuv";
 
 use std::cast;
 use std::fmt;
@@ -69,6 +70,16 @@ pub use self::signal::SignalWatcher;
 pub use self::timer::TimerWatcher;
 pub use self::tty::TtyWatcher;
 
+// Run tests with libgreen instead of libnative.
+//
+// FIXME: This egregiously hacks around starting the test runner in a different
+//        threading mode than the default by reaching into the auto-generated
+//        '__test' module.
+#[cfg(test)] #[start]
+fn start(argc: int, argv: **u8) -> int {
+    green::start(argc, argv, __test::main)
+}
+
 mod macros;
 
 mod access;
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 433400cc9f0..7d734469b12 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -81,6 +81,16 @@
 #[cfg(stage0)]
 pub use vec_ng = vec;
 
+// Run tests with libgreen instead of libnative.
+//
+// FIXME: This egregiously hacks around starting the test runner in a different
+//        threading mode than the default by reaching into the auto-generated
+//        '__test' module.
+#[cfg(test)] #[start]
+fn start(argc: int, argv: **u8) -> int {
+    green::start(argc, argv, __test::main)
+}
+
 pub mod macros;
 
 mod rtdeps;
diff --git a/src/test/run-fail/native-failure.rs b/src/test/run-fail/native-failure.rs
index da00bdf5e0a..377057a75ff 100644
--- a/src/test/run-fail/native-failure.rs
+++ b/src/test/run-fail/native-failure.rs
@@ -11,8 +11,6 @@
 // ignore-android (FIXME #11419)
 // error-pattern:explicit failure
 
-#[no_uv];
-
 extern crate native;
 
 #[start]
diff --git a/src/test/run-make/bootstrap-from-c-with-green/lib.rs b/src/test/run-make/bootstrap-from-c-with-green/lib.rs
index 920474ea9bd..62c5a06dbbf 100644
--- a/src/test/run-make/bootstrap-from-c-with-green/lib.rs
+++ b/src/test/run-make/bootstrap-from-c-with-green/lib.rs
@@ -10,7 +10,6 @@
 
 #[crate_id="boot#0.1"];
 #[crate_type="dylib"];
-#[no_uv];
 
 extern crate rustuv;
 extern crate green;
diff --git a/src/test/run-make/bootstrap-from-c-with-native/lib.rs b/src/test/run-make/bootstrap-from-c-with-native/lib.rs
index 2bc0dbb7770..33c8d4ffab7 100644
--- a/src/test/run-make/bootstrap-from-c-with-native/lib.rs
+++ b/src/test/run-make/bootstrap-from-c-with-native/lib.rs
@@ -10,7 +10,6 @@
 
 #[crate_id="boot#0.1"];
 #[crate_type="dylib"];
-#[no_uv];
 
 extern crate native;
 
diff --git a/src/test/run-pass/capturing-logging.rs b/src/test/run-pass/capturing-logging.rs
index b1db8ad9223..97dfbb0d8e2 100644
--- a/src/test/run-pass/capturing-logging.rs
+++ b/src/test/run-pass/capturing-logging.rs
@@ -14,10 +14,9 @@
 
 #[feature(phase)];
 
-#[no_uv];
-extern crate native;
 #[phase(syntax, link)]
 extern crate log;
+extern crate native;
 
 use std::fmt;
 use std::io::{ChanReader, ChanWriter};
diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs
index db7b2803c71..bda7a30762a 100644
--- a/src/test/run-pass/core-run-destroy.rs
+++ b/src/test/run-pass/core-run-destroy.rs
@@ -9,19 +9,50 @@
 // except according to those terms.
 
 // ignore-fast
+// ignore-pretty
 // compile-flags:--test
 
 // NB: These tests kill child processes. Valgrind sees these children as leaking
 // memory, which makes for some *confusing* logs. That's why these are here
 // instead of in std.
 
-use std::io::timer;
-use std::libc;
-use std::str;
-use std::io::process::{Process, ProcessOutput};
+#[feature(macro_rules)];
 
-#[test]
-fn test_destroy_once() {
+extern crate native;
+extern crate green;
+extern crate rustuv;
+
+macro_rules! iotest (
+    { fn $name:ident() $b:block $($a:attr)* } => (
+        mod $name {
+            #[allow(unused_imports)];
+
+            use std::io::timer;
+            use std::libc;
+            use std::str;
+            use std::io::process::{Process, ProcessOutput};
+            use native;
+            use super::*;
+
+            fn f() $b
+
+            $($a)* #[test] fn green() { f() }
+            $($a)* #[test] fn native() {
+                use native;
+                let (tx, rx) = channel();
+                native::task::spawn(proc() { tx.send(f()) });
+                rx.recv();
+            }
+        }
+    )
+)
+
+#[cfg(test)] #[start]
+fn start(argc: int, argv: **u8) -> int {
+    green::start(argc, argv, __test::main)
+}
+
+iotest!(fn test_destroy_once() {
     #[cfg(not(target_os="android"))]
     static mut PROG: &'static str = "echo";
 
@@ -30,10 +61,9 @@ fn test_destroy_once() {
 
     let mut p = unsafe {Process::new(PROG, []).unwrap()};
     p.signal_exit().unwrap(); // this shouldn't crash (and nor should the destructor)
-}
+})
 
-#[test]
-fn test_destroy_twice() {
+iotest!(fn test_destroy_twice() {
     #[cfg(not(target_os="android"))]
     static mut PROG: &'static str = "echo";
     #[cfg(target_os="android")]
@@ -45,56 +75,27 @@ fn test_destroy_twice() {
     };
     p.signal_exit().unwrap(); // this shouldnt crash...
     p.signal_exit().unwrap(); // ...and nor should this (and nor should the destructor)
-}
+})
 
-fn test_destroy_actually_kills(force: bool) {
+pub fn test_destroy_actually_kills(force: bool) {
+    use std::io::process::{Process, ProcessOutput, ExitStatus, ExitSignal};
+    use std::io::timer;
+    use std::libc;
+    use std::str;
 
     #[cfg(unix,not(target_os="android"))]
-    static mut BLOCK_COMMAND: &'static str = "cat";
+    static BLOCK_COMMAND: &'static str = "cat";
 
     #[cfg(unix,target_os="android")]
-    static mut BLOCK_COMMAND: &'static str = "/system/bin/cat";
+    static BLOCK_COMMAND: &'static str = "/system/bin/cat";
 
     #[cfg(windows)]
-    static mut BLOCK_COMMAND: &'static str = "cmd";
-
-    #[cfg(unix,not(target_os="android"))]
-    fn process_exists(pid: libc::pid_t) -> bool {
-        let ProcessOutput {output, ..} = Process::output("ps", [~"-p", pid.to_str()])
-            .unwrap();
-        str::from_utf8_owned(output).unwrap().contains(pid.to_str())
-    }
-
-    #[cfg(unix,target_os="android")]
-    fn process_exists(pid: libc::pid_t) -> bool {
-        let ProcessOutput {output, ..} = Process::output("/system/bin/ps", [pid.to_str()])
-            .unwrap();
-        str::from_utf8_owned(output).unwrap().contains(~"root")
-    }
-
-    #[cfg(windows)]
-    fn process_exists(pid: libc::pid_t) -> bool {
-        use std::libc::types::os::arch::extra::DWORD;
-        use std::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
-        use std::libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE };
-
-        unsafe {
-            let process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid as DWORD);
-            if process.is_null() {
-                return false;
-            }
-            // process will be non-null if the process is alive, or if it died recently
-            let mut status = 0;
-            GetExitCodeProcess(process, &mut status);
-            CloseHandle(process);
-            return status == STILL_ACTIVE;
-        }
-    }
+    static BLOCK_COMMAND: &'static str = "cmd";
 
     // this process will stay alive indefinitely trying to read from stdin
-    let mut p = unsafe {Process::new(BLOCK_COMMAND, []).unwrap()};
+    let mut p = Process::new(BLOCK_COMMAND, []).unwrap();
 
-    assert!(process_exists(p.id()));
+    assert!(p.signal(0).is_ok());
 
     if force {
         p.signal_kill().unwrap();
@@ -102,18 +103,26 @@ fn test_destroy_actually_kills(force: bool) {
         p.signal_exit().unwrap();
     }
 
-    if process_exists(p.id()) {
-        timer::sleep(500);
-        assert!(!process_exists(p.id()));
+    // Don't let this test time out, this should be quick
+    let (tx, rx1) = channel();
+    let mut t = timer::Timer::new().unwrap();
+    let rx2 = t.oneshot(1000);
+    spawn(proc() {
+        select! {
+            () = rx2.recv() => unsafe { libc::exit(1) },
+            () = rx1.recv() => {}
+        }
+    });
+    match p.wait() {
+        ExitStatus(..) => fail!("expected a signal"),
+        ExitSignal(..) => tx.send(()),
     }
 }
 
-#[test]
-fn test_unforced_destroy_actually_kills() {
+iotest!(fn test_unforced_destroy_actually_kills() {
     test_destroy_actually_kills(false);
-}
+})
 
-#[test]
-fn test_forced_destroy_actually_kills() {
+iotest!(fn test_forced_destroy_actually_kills() {
     test_destroy_actually_kills(true);
-}
+})
diff --git a/src/test/run-pass/native-print-no-runtime.rs b/src/test/run-pass/native-print-no-runtime.rs
index 67de65cea9f..150435959e4 100644
--- a/src/test/run-pass/native-print-no-runtime.rs
+++ b/src/test/run-pass/native-print-no-runtime.rs
@@ -10,8 +10,6 @@
 
 // ignore-fast
 
-#[no_uv];
-
 #[start]
 pub fn main(_: int, _: **u8) -> int {
     println!("hello");
diff --git a/src/test/run-pass/process-detach.rs b/src/test/run-pass/process-detach.rs
index ffb446d1b33..319c2682013 100644
--- a/src/test/run-pass/process-detach.rs
+++ b/src/test/run-pass/process-detach.rs
@@ -20,10 +20,16 @@
 // Note that the first thing we do is put ourselves in our own process group so
 // we don't interfere with other running tests.
 
+extern crate green;
+extern crate rustuv;
+
 use std::libc;
 use std::io::process;
 use std::io::signal::{Listener, Interrupt};
 
+#[start]
+fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
+
 fn main() {
     unsafe { libc::setsid(); }