diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-07-17 18:38:12 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-07-22 14:16:52 -0700 |
| commit | 4beda4e582e4fe008aaf866a5f3ad6a20dec9876 (patch) | |
| tree | 37cb85c47b61b5659ea02c2432399ec6d9fdf0c6 | |
| parent | f8c4d99df67d411d5f7b48823bc082d81cdfaa37 (diff) | |
| download | rust-4beda4e582e4fe008aaf866a5f3ad6a20dec9876.tar.gz rust-4beda4e582e4fe008aaf866a5f3ad6a20dec9876.zip | |
std::rt: Stop using unstable::global in change_dir_locked
| -rw-r--r-- | src/libstd/os.rs | 40 | ||||
| -rw-r--r-- | src/rt/rust_builtin.cpp | 12 | ||||
| -rw-r--r-- | src/rt/rustrt.def.in | 2 |
3 files changed, 40 insertions, 14 deletions
diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 4bfd3bbcd3f..fb5be0494ef 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -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(()) }); - - do result.with_imm() |_| { - let old_dir = os::getcwd(); - if change_dir(p) { - action(); - change_dir(&old_dir) - } - else { - false + // 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 (||{ + 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 diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 863e0a3a99e..4dde01d5f00 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -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++ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 215673be120..e9e0f3b6949 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -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 \ No newline at end of file |
