std::rt: Stop using unstable::global in change_dir_locked
This commit is contained in:
parent
f8c4d99df6
commit
4beda4e582
3 changed files with 39 additions and 13 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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++
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue