summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorBen Blum <bblum@andrew.cmu.edu>2012-08-20 17:58:59 -0400
committerBen Blum <bblum@andrew.cmu.edu>2012-08-20 21:51:39 -0400
commit1aa50bba7c11b8d3e2e66bd55913214fcb05a3cc (patch)
treec08bb565cdda5915aa9b8afed4563068ecb14bb4 /src/libstd
parent05accaa16787285560c6ddb1afe9dec45726a7f4 (diff)
downloadrust-1aa50bba7c11b8d3e2e66bd55913214fcb05a3cc.tar.gz
rust-1aa50bba7c11b8d3e2e66bd55913214fcb05a3cc.zip
Add unwrap for std::arc ARC variants
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/arc.rs50
1 files changed, 48 insertions, 2 deletions
diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs
index 51ee4a5178b..86347c7d3a6 100644
--- a/src/libstd/arc.rs
+++ b/src/libstd/arc.rs
@@ -6,8 +6,8 @@
  * between tasks.
  */
 
-import unsafe::{SharedMutableState,
-                shared_mutable_state, clone_shared_mutable_state,
+import unsafe::{SharedMutableState, shared_mutable_state,
+                clone_shared_mutable_state, unwrap_shared_mutable_state,
                 get_shared_mutable_state, get_shared_immutable_state};
 import sync;
 import sync::{mutex, mutex_with_condvars, rwlock, rwlock_with_condvars};
@@ -93,6 +93,12 @@ fn clone<T: const send>(rc: &arc<T>) -> arc<T> {
     arc { x: unsafe { clone_shared_mutable_state(&rc.x) } }
 }
 
+#[cfg(stage1)]
+fn unwrap<T: const send>(+rc: arc<T>) -> T {
+    let arc { x: x } = rc;
+    unsafe { unwrap_shared_mutable_state(x) }
+}
+
 /****************************************************************************
  * Mutex protected ARC (unsafe)
  ****************************************************************************/
@@ -181,6 +187,18 @@ impl<T: send> &mutex_arc<T> {
     }
 }
 
+// FIXME(#2585) make this a by-move method on the arc
+#[cfg(stage1)]
+fn unwrap_mutex_arc<T: send>(+arc: mutex_arc<T>) -> T {
+    let mutex_arc { x: x } = arc;
+    let inner = unsafe { unwrap_shared_mutable_state(x) };
+    let mutex_arc_inner { failed: failed, data: data, _ } = inner;
+    if failed {
+        fail ~"Can't unwrap poisoned mutex_arc - another task failed inside!"
+    }
+    data
+}
+
 // Common code for {mutex.access,rwlock.write}{,_cond}.
 #[inline(always)]
 #[doc(hidden)]
@@ -347,6 +365,18 @@ impl<T: const send> &rw_arc<T> {
     }
 }
 
+// FIXME(#2585) make this a by-move method on the arc
+#[cfg(stage1)]
+fn unwrap_rw_arc<T: const send>(+arc: rw_arc<T>) -> T {
+    let rw_arc { x: x, _ } = arc;
+    let inner = unsafe { unwrap_shared_mutable_state(x) };
+    let rw_arc_inner { failed: failed, data: data, _ } = inner;
+    if failed {
+        fail ~"Can't unwrap poisoned rw_arc - another task failed inside!"
+    }
+    data
+}
+
 // Borrowck rightly complains about immutably aliasing the rwlock in order to
 // lock it. This wraps the unsafety, with the justification that the 'lock'
 // field is never overwritten; only 'failed' and 'data'.
@@ -497,6 +527,22 @@ mod tests {
         }
     }
     #[test] #[should_fail] #[ignore(cfg(windows))]
+    #[cfg(stage1)]
+    fn test_mutex_arc_unwrap_poison() {
+        let arc = mutex_arc(1);
+        let arc2 = ~(&arc).clone();
+        let (c,p) = pipes::stream();
+        do task::spawn {
+            do arc2.access |one| {
+                c.send(());
+                assert *one == 2;
+            }
+        }
+        let _ = p.recv();
+        let one = unwrap_mutex_arc(arc);
+        assert one == 1;
+    }
+    #[test] #[should_fail] #[ignore(cfg(windows))]
     fn test_rw_arc_poison_wr() {
         let arc = ~rw_arc(1);
         let arc2 = ~arc.clone();