std::rt: Stop using unstable::global in change_dir_locked

This commit is contained in:
Brian Anderson 2013-07-17 18:38:12 -07:00
parent f8c4d99df6
commit 4beda4e582
3 changed files with 39 additions and 13 deletions

View file

@ -869,26 +869,38 @@ pub fn change_dir(p: &Path) -> bool {
/// CWD to what it was before, returning true.
/// Returns false if the directory doesn't exist or if the directory change
/// is otherwise unsuccessful.
/// FIXME #7870 This probably shouldn't be part of the public API
pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
use unstable::global::global_data_clone_create;
use unstable::sync::{Exclusive, exclusive};
fn key(_: Exclusive<()>) { }
use task;
use unstable::finally::Finally;
unsafe {
let result = global_data_clone_create(key, || { ~exclusive(()) });
// This is really sketchy. Using a pthread mutex so descheduling
// in the `action` callback can cause deadlock. Doing it in
// `task::atomically` to try to avoid that, but ... I don't know
// this is all bogus.
return do task::atomically {
rust_take_change_dir_lock();
do result.with_imm() |_| {
let old_dir = os::getcwd();
if change_dir(p) {
action();
change_dir(&old_dir)
}
else {
false
do (||{
let old_dir = os::getcwd();
if change_dir(p) {
action();
change_dir(&old_dir)
}
else {
false
}
}).finally {
rust_drop_change_dir_lock();
}
}
}
extern {
fn rust_take_change_dir_lock();
fn rust_drop_change_dir_lock();
}
}
/// Copies a file from one location to another

View file

@ -947,6 +947,18 @@ rust_get_exit_status_newrt() {
return exit_status;
}
static lock_and_signal change_dir_lock;
extern "C" CDECL void
rust_take_change_dir_lock() {
global_args_lock.lock();
}
extern "C" CDECL void
rust_drop_change_dir_lock() {
global_args_lock.unlock();
}
//
// Local Variables:
// mode: C++

View file

@ -268,3 +268,5 @@ rust_take_global_args_lock
rust_drop_global_args_lock
rust_set_exit_status_newrt
rust_get_exit_status_newrt
rust_take_change_dir_lock
rust_drop_change_dir_lock