Skip to content

Commit 2401c8e

Browse files
committed
std: Move change_dir_locked to unstable. rust-lang#7870
1 parent e70c1cb commit 2401c8e

File tree

4 files changed

+57
-43
lines changed

4 files changed

+57
-43
lines changed

src/libextra/tempfile.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ mod tests {
4848
fn recursive_mkdir_rel() {
4949
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
5050
use std::os;
51+
use std::unstable::change_dir_locked;
5152

5253
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel").
5354
expect("recursive_mkdir_rel");
54-
assert!(do os::change_dir_locked(&root) {
55+
assert!(do change_dir_locked(&root) {
5556
let path = Path("frob");
5657
debug!("recursive_mkdir_rel: Making: %s in cwd %s [%?]", path.to_str(),
5758
os::getcwd().to_str(),
@@ -78,10 +79,11 @@ mod tests {
7879
fn recursive_mkdir_rel_2() {
7980
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
8081
use std::os;
82+
use std::unstable::change_dir_locked;
8183

8284
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel_2").
8385
expect("recursive_mkdir_rel_2");
84-
assert!(do os::change_dir_locked(&root) {
86+
assert!(do change_dir_locked(&root) {
8587
let path = Path("./frob/baz");
8688
debug!("recursive_mkdir_rel_2: Making: %s in cwd %s [%?]", path.to_str(),
8789
os::getcwd().to_str(), os::path_exists(&path));

src/librustpkg/tests.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,12 +742,14 @@ fn rust_path_test() {
742742
743743
#[test]
744744
fn rust_path_contents() {
745+
use std::unstable::change_dir_locked;
746+
745747
let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed");
746748
let abc = &dir.push("A").push("B").push("C");
747749
assert!(os::mkdir_recursive(&abc.push(".rust"), U_RWX));
748750
assert!(os::mkdir_recursive(&abc.pop().push(".rust"), U_RWX));
749751
assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), U_RWX));
750-
assert!(do os::change_dir_locked(&dir.push("A").push("B").push("C")) {
752+
assert!(do change_dir_locked(&dir.push("A").push("B").push("C")) {
751753
let p = rust_path();
752754
let cwd = os::getcwd().push(".rust");
753755
let parent = cwd.pop().pop().push(".rust");

src/libstd/os.rs

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -865,46 +865,6 @@ pub fn change_dir(p: &Path) -> bool {
865865
}
866866
}
867867

868-
/// Changes the current working directory to the specified
869-
/// path while acquiring a global lock, then calls `action`.
870-
/// If the change is successful, releases the lock and restores the
871-
/// CWD to what it was before, returning true.
872-
/// Returns false if the directory doesn't exist or if the directory change
873-
/// is otherwise unsuccessful.
874-
/// FIXME #7870 This probably shouldn't be part of the public API
875-
pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
876-
use task;
877-
use unstable::finally::Finally;
878-
879-
unsafe {
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();
898-
}
899-
}
900-
}
901-
902-
extern {
903-
fn rust_take_change_dir_lock();
904-
fn rust_drop_change_dir_lock();
905-
}
906-
}
907-
908868
/// Copies a file from one location to another
909869
pub fn copy_file(from: &Path, to: &Path) -> bool {
910870
return do_copy_file(from, to);

src/libstd/unstable/mod.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,53 @@ extern {
7979
fn rust_raw_thread_start(f: &(&fn())) -> *raw_thread;
8080
fn rust_raw_thread_join_delete(thread: *raw_thread);
8181
}
82+
83+
84+
/// Changes the current working directory to the specified
85+
/// path while acquiring a global lock, then calls `action`.
86+
/// If the change is successful, releases the lock and restores the
87+
/// CWD to what it was before, returning true.
88+
/// Returns false if the directory doesn't exist or if the directory change
89+
/// is otherwise unsuccessful.
90+
///
91+
/// This is used by test cases to avoid cwd races.
92+
///
93+
/// # Safety Note
94+
///
95+
/// This uses a pthread mutex so descheduling in the action callback
96+
/// can lead to deadlock. Calling change_dir_locked recursively will
97+
/// also deadlock.
98+
pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
99+
use os;
100+
use os::change_dir;
101+
use task;
102+
use unstable::finally::Finally;
103+
104+
unsafe {
105+
// This is really sketchy. Using a pthread mutex so descheduling
106+
// in the `action` callback can cause deadlock. Doing it in
107+
// `task::atomically` to try to avoid that, but ... I don't know
108+
// this is all bogus.
109+
return do task::atomically {
110+
rust_take_change_dir_lock();
111+
112+
do (||{
113+
let old_dir = os::getcwd();
114+
if change_dir(p) {
115+
action();
116+
change_dir(&old_dir)
117+
}
118+
else {
119+
false
120+
}
121+
}).finally {
122+
rust_drop_change_dir_lock();
123+
}
124+
}
125+
}
126+
127+
extern {
128+
fn rust_take_change_dir_lock();
129+
fn rust_drop_change_dir_lock();
130+
}
131+
}

0 commit comments

Comments
 (0)