about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libnative/bookkeeping.rs9
-rw-r--r--src/libnative/io/timer_helper.rs21
-rw-r--r--src/test/run-pass/issue-12699.rs22
3 files changed, 36 insertions, 16 deletions
diff --git a/src/libnative/bookkeeping.rs b/src/libnative/bookkeeping.rs
index b1addc5cda5..76e58ce753f 100644
--- a/src/libnative/bookkeeping.rs
+++ b/src/libnative/bookkeeping.rs
@@ -39,12 +39,9 @@ pub fn decrement() {
 /// the entry points of native programs
 pub fn wait_for_other_tasks() {
     unsafe {
-        {
-            let mut guard = TASK_LOCK.lock();
-            while TASK_COUNT.load(atomics::SeqCst) > 0 {
-                guard.wait();
-            }
+        let mut guard = TASK_LOCK.lock();
+        while TASK_COUNT.load(atomics::SeqCst) > 0 {
+            guard.wait();
         }
-        TASK_LOCK.destroy();
     }
 }
diff --git a/src/libnative/io/timer_helper.rs b/src/libnative/io/timer_helper.rs
index 7669d4a658f..45bd0f8b67c 100644
--- a/src/libnative/io/timer_helper.rs
+++ b/src/libnative/io/timer_helper.rs
@@ -36,6 +36,8 @@ use task;
 static mut HELPER_CHAN: *mut Chan<Req> = 0 as *mut Chan<Req>;
 static mut HELPER_SIGNAL: imp::signal = 0 as imp::signal;
 
+static mut TIMER_HELPER_EXIT: StaticNativeMutex = NATIVE_MUTEX_INIT;
+
 pub fn boot(helper: fn(imp::signal, Port<Req>)) {
     static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
     static mut INITIALIZED: bool = false;
@@ -53,6 +55,7 @@ pub fn boot(helper: fn(imp::signal, Port<Req>)) {
             task::spawn(proc() {
                 bookkeeping::decrement();
                 helper(receive, msgp);
+                TIMER_HELPER_EXIT.lock().signal()
             });
 
             rt::at_exit(proc() { shutdown() });
@@ -70,17 +73,15 @@ pub fn send(req: Req) {
 }
 
 fn shutdown() {
-    // We want to wait for the entire helper task to exit, and in doing so it
-    // will attempt to decrement the global task count. When the helper was
-    // created, it decremented the count so it wouldn't count towards preventing
-    // the program to exit, so here we pair that manual decrement with a manual
-    // increment. We will then wait for the helper thread to exit by calling
-    // wait_for_other_tasks.
-    bookkeeping::increment();
-
     // Request a shutdown, and then wait for the task to exit
-    send(Shutdown);
-    bookkeeping::wait_for_other_tasks();
+    unsafe {
+        let mut guard = TIMER_HELPER_EXIT.lock();
+        send(Shutdown);
+        guard.wait();
+        drop(guard);
+        TIMER_HELPER_EXIT.destroy();
+    }
+
 
     // Clean up after ther helper thread
     unsafe {
diff --git a/src/test/run-pass/issue-12699.rs b/src/test/run-pass/issue-12699.rs
new file mode 100644
index 00000000000..24f9a05b2c1
--- /dev/null
+++ b/src/test/run-pass/issue-12699.rs
@@ -0,0 +1,22 @@
+// Copyright 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.
+
+extern crate native;
+
+use std::io::timer;
+
+#[start]
+fn start(argc: int, argv: **u8) -> int {
+    native::start(argc, argv, main)
+}
+
+fn main() {
+    timer::sleep(250);
+}