about summary refs log tree commit diff
path: root/src/libextra
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-05-23 19:12:16 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-05-29 19:04:50 -0700
commitaeda178011775f4a8e16446341fe4774e02d8f5f (patch)
tree6e96ca95949ebee511eea69ebe1a854cc31dee0a /src/libextra
parentb5da389d36ec9108f82bb7025eabb7ce4f26b103 (diff)
downloadrust-aeda178011775f4a8e16446341fe4774e02d8f5f.tar.gz
rust-aeda178011775f4a8e16446341fe4774e02d8f5f.zip
librustc: Redo the unsafe checker and make unsafe methods not callable from safe code
Diffstat (limited to 'src/libextra')
-rw-r--r--src/libextra/arc.rs18
-rw-r--r--src/libextra/sync.rs94
2 files changed, 61 insertions, 51 deletions
diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs
index 4baa1168b3b..e120f3dd033 100644
--- a/src/libextra/arc.rs
+++ b/src/libextra/arc.rs
@@ -198,13 +198,15 @@ pub impl<T:Owned> MutexARC<T> {
      */
     #[inline(always)]
     unsafe fn access<U>(&self, blk: &fn(x: &mut T) -> U) -> U {
-        let state = self.x.get();
-        // Borrowck would complain about this if the function were
-        // not already unsafe. See borrow_rwlock, far below.
-        do (&(*state).lock).lock {
-            check_poison(true, (*state).failed);
-            let _z = PoisonOnFail(&mut (*state).failed);
-            blk(&mut (*state).data)
+        unsafe {
+            let state = self.x.get();
+            // Borrowck would complain about this if the function were
+            // not already unsafe. See borrow_rwlock, far below.
+            do (&(*state).lock).lock {
+                check_poison(true, (*state).failed);
+                let _z = PoisonOnFail(&mut (*state).failed);
+                blk(&mut (*state).data)
+            }
         }
     }
 
@@ -356,8 +358,8 @@ pub impl<T:Const + Owned> RWARC<T> {
      * access modes, this will not poison the ARC.
      */
     fn read<U>(&self, blk: &fn(x: &T) -> U) -> U {
-        let state = self.x.get();
         unsafe {
+            let state = self.x.get();
             do (*state).lock.read {
                 check_poison(false, (*state).failed);
                 blk(&(*state).data)
diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs
index 48f34fdf46a..beea3b6f52b 100644
--- a/src/libextra/sync.rs
+++ b/src/libextra/sync.rs
@@ -100,30 +100,34 @@ fn new_sem_and_signal(count: int, num_condvars: uint)
 #[doc(hidden)]
 pub impl<Q:Owned> Sem<Q> {
     fn acquire(&self) {
-        let mut waiter_nobe = None;
-        do (**self).with |state| {
-            state.count -= 1;
-            if state.count < 0 {
-                // Create waiter nobe.
-                let (WaitEnd, SignalEnd) = comm::oneshot();
-                // Tell outer scope we need to block.
-                waiter_nobe = Some(WaitEnd);
-                // Enqueue ourself.
-                state.waiters.tail.send(SignalEnd);
+        unsafe {
+            let mut waiter_nobe = None;
+            do (**self).with |state| {
+                state.count -= 1;
+                if state.count < 0 {
+                    // Create waiter nobe.
+                    let (WaitEnd, SignalEnd) = comm::oneshot();
+                    // Tell outer scope we need to block.
+                    waiter_nobe = Some(WaitEnd);
+                    // Enqueue ourself.
+                    state.waiters.tail.send(SignalEnd);
+                }
+            }
+            // Uncomment if you wish to test for sem races. Not valgrind-friendly.
+            /* for 1000.times { task::yield(); } */
+            // Need to wait outside the exclusive.
+            if waiter_nobe.is_some() {
+                let _ = comm::recv_one(waiter_nobe.unwrap());
             }
-        }
-        // Uncomment if you wish to test for sem races. Not valgrind-friendly.
-        /* for 1000.times { task::yield(); } */
-        // Need to wait outside the exclusive.
-        if waiter_nobe.is_some() {
-            let _ = comm::recv_one(waiter_nobe.unwrap());
         }
     }
     fn release(&self) {
-        do (**self).with |state| {
-            state.count += 1;
-            if state.count <= 0 {
-                signal_waitqueue(&state.waiters);
+        unsafe {
+            do (**self).with |state| {
+                state.count += 1;
+                if state.count <= 0 {
+                    signal_waitqueue(&state.waiters);
+                }
             }
         }
     }
@@ -283,17 +287,19 @@ pub impl<'self> Condvar<'self> {
 
     /// As signal, but with a specified condvar_id. See wait_on.
     fn signal_on(&self, condvar_id: uint) -> bool {
-        let mut out_of_bounds = None;
-        let mut result = false;
-        do (**self.sem).with |state| {
-            if condvar_id < state.blocked.len() {
-                result = signal_waitqueue(&state.blocked[condvar_id]);
-            } else {
-                out_of_bounds = Some(state.blocked.len());
+        unsafe {
+            let mut out_of_bounds = None;
+            let mut result = false;
+            do (**self.sem).with |state| {
+                if condvar_id < state.blocked.len() {
+                    result = signal_waitqueue(&state.blocked[condvar_id]);
+                } else {
+                    out_of_bounds = Some(state.blocked.len());
+                }
+            }
+            do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") {
+                result
             }
-        }
-        do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") {
-            result
         }
     }
 
@@ -304,20 +310,22 @@ pub impl<'self> Condvar<'self> {
     fn broadcast_on(&self, condvar_id: uint) -> uint {
         let mut out_of_bounds = None;
         let mut queue = None;
-        do (**self.sem).with |state| {
-            if condvar_id < state.blocked.len() {
-                // To avoid :broadcast_heavy, we make a new waitqueue,
-                // swap it out with the old one, and broadcast on the
-                // old one outside of the little-lock.
-                queue = Some(util::replace(&mut state.blocked[condvar_id],
-                                           new_waitqueue()));
-            } else {
-                out_of_bounds = Some(state.blocked.len());
+        unsafe {
+            do (**self.sem).with |state| {
+                if condvar_id < state.blocked.len() {
+                    // To avoid :broadcast_heavy, we make a new waitqueue,
+                    // swap it out with the old one, and broadcast on the
+                    // old one outside of the little-lock.
+                    queue = Some(util::replace(&mut state.blocked[condvar_id],
+                                               new_waitqueue()));
+                } else {
+                    out_of_bounds = Some(state.blocked.len());
+                }
+            }
+            do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") {
+                let queue = queue.swap_unwrap();
+                broadcast_waitqueue(&queue)
             }
-        }
-        do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") {
-            let queue = queue.swap_unwrap();
-            broadcast_waitqueue(&queue)
         }
     }
 }