diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2013-05-23 19:12:16 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2013-05-29 19:04:50 -0700 |
| commit | aeda178011775f4a8e16446341fe4774e02d8f5f (patch) | |
| tree | 6e96ca95949ebee511eea69ebe1a854cc31dee0a /src/libextra | |
| parent | b5da389d36ec9108f82bb7025eabb7ce4f26b103 (diff) | |
| download | rust-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.rs | 18 | ||||
| -rw-r--r-- | src/libextra/sync.rs | 94 |
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) } } } |
