about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-07-17 18:59:29 -0700
committerBrian Anderson <banderson@mozilla.com>2013-07-22 14:16:52 -0700
commit6174f9a4d9dc48f9988cd252f4fea8b319020298 (patch)
tree4ae693685d847ab5d00a0c6dbff6eb950ae7769c
parent4beda4e582e4fe008aaf866a5f3ad6a20dec9876 (diff)
downloadrust-6174f9a4d9dc48f9988cd252f4fea8b319020298.tar.gz
rust-6174f9a4d9dc48f9988cd252f4fea8b319020298.zip
std: Move change_dir_locked to unstable. #7870
-rw-r--r--src/libextra/tempfile.rs6
-rw-r--r--src/librustpkg/tests.rs4
-rw-r--r--src/libstd/os.rs40
-rw-r--r--src/libstd/unstable/mod.rs50
4 files changed, 57 insertions, 43 deletions
diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs
index f8948f41101..c5fb4b9292e 100644
--- a/src/libextra/tempfile.rs
+++ b/src/libextra/tempfile.rs
@@ -48,10 +48,11 @@ mod tests {
     fn recursive_mkdir_rel() {
         use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
         use std::os;
+        use std::unstable::change_dir_locked;
 
         let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel").
             expect("recursive_mkdir_rel");
-        assert!(do os::change_dir_locked(&root) {
+        assert!(do change_dir_locked(&root) {
             let path = Path("frob");
             debug!("recursive_mkdir_rel: Making: %s in cwd %s [%?]", path.to_str(),
                    os::getcwd().to_str(),
@@ -78,10 +79,11 @@ mod tests {
     fn recursive_mkdir_rel_2() {
         use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
         use std::os;
+        use std::unstable::change_dir_locked;
 
         let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel_2").
             expect("recursive_mkdir_rel_2");
-        assert!(do os::change_dir_locked(&root) {
+        assert!(do change_dir_locked(&root) {
             let path = Path("./frob/baz");
             debug!("recursive_mkdir_rel_2: Making: %s in cwd %s [%?]", path.to_str(),
                    os::getcwd().to_str(), os::path_exists(&path));
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index e6cda8286aa..286b1f84802 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -791,12 +791,14 @@ fn rust_path_test() {
 
 #[test]
 fn rust_path_contents() {
+    use std::unstable::change_dir_locked;
+
     let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed");
     let abc = &dir.push("A").push("B").push("C");
     assert!(os::mkdir_recursive(&abc.push(".rust"), U_RWX));
     assert!(os::mkdir_recursive(&abc.pop().push(".rust"), U_RWX));
     assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), U_RWX));
-    assert!(do os::change_dir_locked(&dir.push("A").push("B").push("C")) {
+    assert!(do change_dir_locked(&dir.push("A").push("B").push("C")) {
         let p = rust_path();
         let cwd = os::getcwd().push(".rust");
         let parent = cwd.pop().pop().push(".rust");
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index fb5be0494ef..5981926fce3 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -863,46 +863,6 @@ pub fn change_dir(p: &Path) -> bool {
     }
 }
 
-/// Changes the current working directory to the specified
-/// path while acquiring a global lock, then calls `action`.
-/// If the change is successful, releases the lock and restores the
-/// 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 task;
-    use unstable::finally::Finally;
-
-    unsafe {
-        // 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
 pub fn copy_file(from: &Path, to: &Path) -> bool {
     return do_copy_file(from, to);
diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs
index c7e88b7e161..e6313a10db1 100644
--- a/src/libstd/unstable/mod.rs
+++ b/src/libstd/unstable/mod.rs
@@ -79,3 +79,53 @@ extern {
     fn rust_raw_thread_start(f: &(&fn())) -> *raw_thread;
     fn rust_raw_thread_join_delete(thread: *raw_thread);
 }
+
+
+/// Changes the current working directory to the specified
+/// path while acquiring a global lock, then calls `action`.
+/// If the change is successful, releases the lock and restores the
+/// CWD to what it was before, returning true.
+/// Returns false if the directory doesn't exist or if the directory change
+/// is otherwise unsuccessful.
+///
+/// This is used by test cases to avoid cwd races.
+///
+/// # Safety Note
+///
+/// This uses a pthread mutex so descheduling in the action callback
+/// can lead to deadlock. Calling change_dir_locked recursively will
+/// also deadlock.
+pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
+    use os;
+    use os::change_dir;
+    use task;
+    use unstable::finally::Finally;
+
+    unsafe {
+        // 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();
+    }
+}