diff options
| author | bors <bors@rust-lang.org> | 2014-03-06 00:41:48 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-03-06 00:41:48 -0800 |
| commit | 2fba2fea121b616793287f33aa3ee05e8d8893b0 (patch) | |
| tree | 7b6d2bd1a7449d81b9b6acb7c1099eca91df414d /src/libstd | |
| parent | 2153293ae434861c72469d41fc7c9dfe9b90b1c4 (diff) | |
| parent | 9668ab58f338b27d8f53357c7fd4ea3d3f06305e (diff) | |
| download | rust-2fba2fea121b616793287f33aa3ee05e8d8893b0.tar.gz rust-2fba2fea121b616793287f33aa3ee05e8d8893b0.zip | |
auto merge of #12705 : alexcrichton/rust/issue-12692, r=brson
Details are in the commit messages, but this closes a few issues seen with `libnative` recently.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/libc.rs | 11 | ||||
| -rw-r--r-- | src/libstd/rt/bookkeeping.rs | 52 | ||||
| -rw-r--r-- | src/libstd/rt/mod.rs | 4 |
3 files changed, 64 insertions, 3 deletions
diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 0ef8570ce30..afd524e9d7a 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -3658,13 +3658,16 @@ pub mod funcs { pub unsafe fn opendir(dirname: *c_char) -> *DIR { rust_opendir(dirname) } - pub unsafe fn readdir(dirp: *DIR) -> *dirent_t { - rust_readdir(dirp) + pub unsafe fn readdir_r(dirp: *DIR, + entry: *mut dirent_t, + result: *mut *mut dirent_t) -> c_int { + rust_readdir_r(dirp, entry, result) } extern { fn rust_opendir(dirname: *c_char) -> *DIR; - fn rust_readdir(dirp: *DIR) -> *dirent_t; + fn rust_readdir_r(dirp: *DIR, entry: *mut dirent_t, + result: *mut *mut dirent_t) -> c_int; } extern { @@ -3680,6 +3683,7 @@ pub mod funcs { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_char, c_int, c_long, c_uint}; use libc::types::os::arch::c95::{size_t}; + use libc::types::os::common::posix01::timespec; use libc::types::os::arch::posix01::utimbuf; use libc::types::os::arch::posix88::{gid_t, off_t, pid_t}; use libc::types::os::arch::posix88::{ssize_t, uid_t}; @@ -3729,6 +3733,7 @@ pub mod funcs { pub fn setuid(uid: uid_t) -> c_int; pub fn sleep(secs: c_uint) -> c_uint; pub fn usleep(secs: c_uint) -> c_int; + pub fn nanosleep(rqtp: *timespec, rmtp: *mut timespec) -> c_int; pub fn sysconf(name: c_int) -> c_long; pub fn tcgetpgrp(fd: c_int) -> pid_t; pub fn ttyname(fd: c_int) -> *c_char; diff --git a/src/libstd/rt/bookkeeping.rs b/src/libstd/rt/bookkeeping.rs new file mode 100644 index 00000000000..5851a6a39c6 --- /dev/null +++ b/src/libstd/rt/bookkeeping.rs @@ -0,0 +1,52 @@ +// 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. + +//! Task bookkeeping +//! +//! 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, and it's up to +//! each respective runtime to make sure that they call increment() and +//! decrement() manually. + +#[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; + +pub fn increment() { + let _ = unsafe { TASK_COUNT.fetch_add(1, atomics::SeqCst) }; +} + +pub fn decrement() { + unsafe { + if TASK_COUNT.fetch_sub(1, atomics::SeqCst) == 1 { + let mut guard = TASK_LOCK.lock(); + guard.signal(); + } + } +} + +/// Waits for all other native tasks in the system to exit. This is only used by +/// 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(); + } + } +} 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(); |
