Skip to content

Commit e70c1cb

Browse files
committed
std::rt: Stop using unstable::global in change_dir_locked
1 parent 31ef99e commit e70c1cb

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

src/libstd/os.rs

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

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

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

src/rt/rust_builtin.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,18 @@ rust_get_exit_status_newrt() {
953953
return exit_status;
954954
}
955955

956+
static lock_and_signal change_dir_lock;
957+
958+
extern "C" CDECL void
959+
rust_take_change_dir_lock() {
960+
global_args_lock.lock();
961+
}
962+
963+
extern "C" CDECL void
964+
rust_drop_change_dir_lock() {
965+
global_args_lock.unlock();
966+
}
967+
956968
//
957969
// Local Variables:
958970
// mode: C++

src/rt/rustrt.def.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,5 @@ rust_take_global_args_lock
269269
rust_drop_global_args_lock
270270
rust_set_exit_status_newrt
271271
rust_get_exit_status_newrt
272+
rust_take_change_dir_lock
273+
rust_drop_change_dir_lock

0 commit comments

Comments
 (0)