]> git.lizzy.rs Git - rust.git/commitdiff
std::rt: Stop using unstable::global in change_dir_locked
authorBrian Anderson <banderson@mozilla.com>
Thu, 18 Jul 2013 01:38:12 +0000 (18:38 -0700)
committerBrian Anderson <banderson@mozilla.com>
Mon, 22 Jul 2013 21:16:52 +0000 (14:16 -0700)
src/libstd/os.rs
src/rt/rust_builtin.cpp
src/rt/rustrt.def.in

index 4bfd3bbcd3ff1c563a91b99c6795881273dcecdd..fb5be0494ef0a541157a1e34089f40eb511c33cb 100644 (file)
@@ -869,26 +869,38 @@ fn chdir(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
index 863e0a3a99e17d9049db0f4affdeb004a6cdd781..4dde01d5f00c664967ee921f4e1e39f0908b8f27 100644 (file)
@@ -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++
index 215673be1203ed27116bd2784f4a20d71bf6ffa3..e9e0f3b694909f7afe8113d37480178864dfc1cd 100644 (file)
@@ -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