about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-03-05 10:35:30 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-03-05 21:48:08 -0800
commit9668ab58f338b27d8f53357c7fd4ea3d3f06305e (patch)
treea51174739f9ed9c1910d9676a29a818d49a15009
parente6acff828787b9b6c65ef66942f45e58b2f22ad6 (diff)
downloadrust-9668ab58f338b27d8f53357c7fd4ea3d3f06305e.tar.gz
rust-9668ab58f338b27d8f53357c7fd4ea3d3f06305e.zip
std: Move libnative task count bookkeeping to std
When using tasks in Rust, the expectation is that the runtime does not exit
before all tasks have exited. This is enforced in libgreen through the
`SchedPool` type, and it is enforced in libnative through a `bookkeeping` module
and a global count/mutex pair. Unfortunately, this means that a process which
originates with libgreen will not wait for spawned native tasks.

In order to fix this problem, the bookkeeping module was moved from libnative to
libstd so the runtime itself can wait for native tasks to exit. Green tasks do
not manage themselves through this bookkeeping module, but native tasks will
continue to manage themselves through this module.

Closes #12684
-rw-r--r--src/libnative/io/timer_helper.rs2
-rw-r--r--src/libnative/lib.rs2
-rw-r--r--src/libnative/task.rs4
-rw-r--r--src/libstd/rt/bookkeeping.rs (renamed from src/libnative/bookkeeping.rs)19
-rw-r--r--src/libstd/rt/mod.rs4
-rw-r--r--src/test/run-pass/issue-12684.rs28
-rw-r--r--src/test/run-pass/issue-12699.rs2
7 files changed, 49 insertions, 12 deletions
diff --git a/src/libnative/io/timer_helper.rs b/src/libnative/io/timer_helper.rs
index 45bd0f8b67c..62e41771423 100644
--- a/src/libnative/io/timer_helper.rs
+++ b/src/libnative/io/timer_helper.rs
@@ -21,10 +21,10 @@
 //! time.
 
 use std::cast;
+use std::rt::bookkeeping;
 use std::rt;
 use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
 
-use bookkeeping;
 use io::timer::{Req, Shutdown};
 use task;
 
diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs
index 378283973db..4b6942a1083 100644
--- a/src/libnative/lib.rs
+++ b/src/libnative/lib.rs
@@ -58,7 +58,6 @@
 use std::os;
 use std::rt;
 
-mod bookkeeping;
 pub mod io;
 pub mod task;
 
@@ -105,6 +104,5 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
 /// number of arguments.
 pub fn run(main: proc()) -> int {
     main();
-    bookkeeping::wait_for_other_tasks();
     os::get_exit_status()
 }
diff --git a/src/libnative/task.rs b/src/libnative/task.rs
index aa3afd4c1a5..793e4d48e13 100644
--- a/src/libnative/task.rs
+++ b/src/libnative/task.rs
@@ -16,19 +16,19 @@
 
 use std::any::Any;
 use std::cast;
+use std::rt::bookkeeping;
 use std::rt::env;
 use std::rt::local::Local;
 use std::rt::rtio;
+use std::rt::stack;
 use std::rt::task::{Task, BlockedTask, SendMessage};
 use std::rt::thread::Thread;
 use std::rt;
 use std::task::TaskOpts;
 use std::unstable::mutex::NativeMutex;
-use std::rt::stack;
 
 use io;
 use task;
-use bookkeeping;
 
 /// Creates a new Task which is ready to execute as a 1:1 task.
 pub fn new(stack_bounds: (uint, uint)) -> ~Task {
diff --git a/src/libnative/bookkeeping.rs b/src/libstd/rt/bookkeeping.rs
index 76e58ce753f..5851a6a39c6 100644
--- a/src/libnative/bookkeeping.rs
+++ b/src/libstd/rt/bookkeeping.rs
@@ -8,16 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! 1:1 Task bookkeeping
+//! Task bookkeeping
 //!
-//! This module keeps track of the number of running 1:1 tasks so that entry
-//! points with libnative know when it's possible to exit the program (once all
-//! tasks have exited).
+//! This module keeps track of the number of running tasks so that entry points
+//! with libnative know when it's possible to exit the program (once all tasks
+//! have exited).
 //!
-//! The green counterpart for this is bookkeeping on sched pools.
+//! The green counterpart for this is bookkeeping on sched pools, and it's up to
+//! each respective runtime to make sure that they call increment() and
+//! decrement() manually.
 
-use std::sync::atomics;
-use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+#[experimental]; // this is a massive code smell
+#[doc(hidden)];
+
+use sync::atomics;
+use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
 
 static mut TASK_COUNT: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
 static mut TASK_LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 2f1a6989092..459bc061c56 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -128,6 +128,9 @@ pub mod args;
 // Support for running procedures when a program has exited.
 mod at_exit_imp;
 
+// Bookkeeping for task counts
+pub mod bookkeeping;
+
 // Stack overflow protection
 pub mod stack;
 
@@ -207,6 +210,7 @@ pub fn at_exit(f: proc()) {
 /// Invoking cleanup while portions of the runtime are still in use may cause
 /// undefined behavior.
 pub unsafe fn cleanup() {
+    bookkeeping::wait_for_other_tasks();
     at_exit_imp::run();
     args::cleanup();
     local_ptr::cleanup();
diff --git a/src/test/run-pass/issue-12684.rs b/src/test/run-pass/issue-12684.rs
new file mode 100644
index 00000000000..a6eef4e2021
--- /dev/null
+++ b/src/test/run-pass/issue-12684.rs
@@ -0,0 +1,28 @@
+// Copyright 2013-2014 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.
+
+// ignore-fast
+
+extern crate native;
+extern crate green;
+extern crate rustuv;
+
+#[start]
+fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
+
+fn main() {
+    native::task::spawn(proc() customtask());
+}
+
+fn customtask() {
+    let mut timer = std::io::timer::Timer::new().unwrap();
+    let periodic = timer.periodic(10);
+    periodic.recv();
+}
diff --git a/src/test/run-pass/issue-12699.rs b/src/test/run-pass/issue-12699.rs
index 24f9a05b2c1..6409ba51375 100644
--- a/src/test/run-pass/issue-12699.rs
+++ b/src/test/run-pass/issue-12699.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-fast
+
 extern crate native;
 
 use std::io::timer;