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 /src/libstd | |
| parent | f8c4d99df67d411d5f7b48823bc082d81cdfaa37 (diff) | |
| download | rust-4beda4e582e4fe008aaf866a5f3ad6a20dec9876.tar.gz rust-4beda4e582e4fe008aaf866a5f3ad6a20dec9876.zip | |
std::rt: Stop using unstable::global in change_dir_locked
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/os.rs | 40 |
1 files changed, 26 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 |
