Skip to content

Commit 4beda4e

Browse files
committed
std::rt: Stop using unstable::global in change_dir_locked
1 parent f8c4d99 commit 4beda4e

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

src/libstd/os.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -869,26 +869,38 @@ pub fn change_dir(p: &Path) -> bool {
869869
/// CWD to what it was before, returning true.
870870
/// Returns false if the directory doesn't exist or if the directory change
871871
/// is otherwise unsuccessful.
872+
/// FIXME #7870 This probably shouldn't be part of the public API
872873
pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
873-
use unstable::global::global_data_clone_create;
874-
use unstable::sync::{Exclusive, exclusive};
875-
876-
fn key(_: Exclusive<()>) { }
874+
use task;
875+
use unstable::finally::Finally;
877876

878877
unsafe {
879-
let result = global_data_clone_create(key, || { ~exclusive(()) });
880-
881-
do result.with_imm() |_| {
882-
let old_dir = os::getcwd();
883-
if change_dir(p) {
884-
action();
885-
change_dir(&old_dir)
886-
}
887-
else {
888-
false
878+
// This is really sketchy. Using a pthread mutex so descheduling
879+
// in the `action` callback can cause deadlock. Doing it in
880+
// `task::atomically` to try to avoid that, but ... I don't know
881+
// this is all bogus.
882+
return do task::atomically {
883+
rust_take_change_dir_lock();
884+
885+
do (||{
886+
let old_dir = os::getcwd();
887+
if change_dir(p) {
888+
action();
889+
change_dir(&old_dir)
890+
}
891+
else {
892+
false
893+
}
894+
}).finally {
895+
rust_drop_change_dir_lock();
889896
}
890897
}
891898
}
899+
900+
extern {
901+
fn rust_take_change_dir_lock();
902+
fn rust_drop_change_dir_lock();
903+
}
892904
}
893905

894906
/// Copies a file from one location to another

src/rt/rust_builtin.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,18 @@ rust_get_exit_status_newrt() {
947947
return exit_status;
948948
}
949949

950+
static lock_and_signal change_dir_lock;
951+
952+
extern "C" CDECL void
953+
rust_take_change_dir_lock() {
954+
global_args_lock.lock();
955+
}
956+
957+
extern "C" CDECL void
958+
rust_drop_change_dir_lock() {
959+
global_args_lock.unlock();
960+
}
961+
950962
//
951963
// Local Variables:
952964
// mode: C++

src/rt/rustrt.def.in

+2
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,5 @@ rust_take_global_args_lock
268268
rust_drop_global_args_lock
269269
rust_set_exit_status_newrt
270270
rust_get_exit_status_newrt
271+
rust_take_change_dir_lock
272+
rust_drop_change_dir_lock

0 commit comments

Comments
 (0)