diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/libnative/bookkeeping.rs | 9 | ||||
| -rw-r--r-- | src/libnative/io/timer_helper.rs | 21 | ||||
| -rw-r--r-- | src/test/run-pass/issue-12699.rs | 22 |
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); +} |
