diff options
| author | bors <bors@rust-lang.org> | 2013-02-12 20:40:19 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-02-12 20:40:19 -0800 |
| commit | 27b3e01377ff9b25a38a76937c3d14cd9d0fb2b0 (patch) | |
| tree | d2f3367752c8410f35d30671b8dc175eb55db3c4 /src/libstd | |
| parent | 1a394e57f7a622e67c13eae8bc26848eea31334a (diff) | |
| parent | ab2534974caf39e69b401442ff1a9077b94c46c1 (diff) | |
| download | rust-27b3e01377ff9b25a38a76937c3d14cd9d0fb2b0.tar.gz rust-27b3e01377ff9b25a38a76937c3d14cd9d0fb2b0.zip | |
auto merge of #4914 : nikomatsakis/rust/issue-4856, r=nikomatsakis
and then adjust code to match. rs=unsound (will review post-landing) rs=unsound
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/arc.rs | 85 | ||||
| -rw-r--r-- | src/libstd/priority_queue.rs | 6 | ||||
| -rw-r--r-- | src/libstd/smallintmap.rs | 9 | ||||
| -rw-r--r-- | src/libstd/treemap.rs | 56 |
4 files changed, 87 insertions, 69 deletions
diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index a1fd7a66f7e..ff28d2cbebf 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -184,25 +184,30 @@ impl<T: Owned> &MutexARC<T> { */ #[inline(always)] unsafe fn access<U>(blk: fn(x: &mut T) -> U) -> U { - let state = unsafe { get_shared_mutable_state(&self.x) }; - // 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 = get_shared_mutable_state(&self.x); + // 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) + } } } /// As access(), but with a condvar, as sync::mutex.lock_cond(). #[inline(always)] unsafe fn access_cond<U>(blk: fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { - let state = unsafe { get_shared_mutable_state(&self.x) }; - do (&state.lock).lock_cond |cond| { - check_poison(true, state.failed); - let _z = PoisonOnFail(&mut state.failed); - blk(&mut state.data, - &Condvar { is_mutex: true, failed: &mut state.failed, - cond: cond }) + unsafe { + let state = get_shared_mutable_state(&self.x); + do (&(*state).lock).lock_cond |cond| { + check_poison(true, (*state).failed); + let _z = PoisonOnFail(&mut (*state).failed); + blk(&mut (*state).data, + &Condvar {is_mutex: true, + failed: &mut (*state).failed, + cond: cond }) + } } } } @@ -285,8 +290,10 @@ pub fn RWARC<T: Const Owned>(user_data: T) -> RWARC<T> { * Create a reader/writer ARC with the supplied data and a specified number * of condvars (as sync::rwlock_with_condvars). */ -pub fn rw_arc_with_condvars<T: Const Owned>(user_data: T, - num_condvars: uint) -> RWARC<T> { +pub fn rw_arc_with_condvars<T: Const Owned>( + user_data: T, + num_condvars: uint) -> RWARC<T> +{ let data = RWARCInner { lock: rwlock_with_condvars(num_condvars), failed: false, data: move user_data }; @@ -315,23 +322,28 @@ impl<T: Const Owned> &RWARC<T> { */ #[inline(always)] fn write<U>(blk: fn(x: &mut T) -> U) -> U { - let state = unsafe { get_shared_mutable_state(&self.x) }; - do borrow_rwlock(state).write { - check_poison(false, state.failed); - let _z = PoisonOnFail(&mut state.failed); - blk(&mut state.data) + unsafe { + let state = get_shared_mutable_state(&self.x); + do (*borrow_rwlock(state)).write { + check_poison(false, (*state).failed); + let _z = PoisonOnFail(&mut (*state).failed); + blk(&mut (*state).data) + } } } /// As write(), but with a condvar, as sync::rwlock.write_cond(). #[inline(always)] fn write_cond<U>(blk: fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { - let state = unsafe { get_shared_mutable_state(&self.x) }; - do borrow_rwlock(state).write_cond |cond| { - check_poison(false, state.failed); - let _z = PoisonOnFail(&mut state.failed); - blk(&mut state.data, - &Condvar { is_mutex: false, failed: &mut state.failed, - cond: cond }) + unsafe { + let state = get_shared_mutable_state(&self.x); + do (*borrow_rwlock(state)).write_cond |cond| { + check_poison(false, (*state).failed); + let _z = PoisonOnFail(&mut (*state).failed); + blk(&mut (*state).data, + &Condvar {is_mutex: false, + failed: &mut (*state).failed, + cond: cond}) + } } } /** @@ -369,11 +381,14 @@ impl<T: Const Owned> &RWARC<T> { * ~~~ */ fn write_downgrade<U>(blk: fn(v: RWWriteMode<T>) -> U) -> U { - let state = unsafe { get_shared_mutable_state(&self.x) }; - do borrow_rwlock(state).write_downgrade |write_mode| { - check_poison(false, state.failed); - blk(RWWriteMode((&mut state.data, move write_mode, - PoisonOnFail(&mut state.failed)))) + unsafe { + let state = get_shared_mutable_state(&self.x); + do (*borrow_rwlock(state)).write_downgrade |write_mode| { + check_poison(false, (*state).failed); + blk(RWWriteMode((&mut (*state).data, + move write_mode, + PoisonOnFail(&mut (*state).failed)))) + } } } @@ -417,8 +432,8 @@ pub fn unwrap_rw_arc<T: Const Owned>(arc: RWARC<T>) -> T { // lock it. This wraps the unsafety, with the justification that the 'lock' // field is never overwritten; only 'failed' and 'data'. #[doc(hidden)] -fn borrow_rwlock<T: Const Owned>(state: &r/mut RWARCInner<T>) -> &r/RWlock { - unsafe { cast::transmute(&mut state.lock) } +fn borrow_rwlock<T: Const Owned>(state: *const RWARCInner<T>) -> *RWlock { + unsafe { cast::transmute(&const (*state).lock) } } // FIXME (#3154) ice with struct/&<T> prevents these from being structs. diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index 5248ab1742e..a64aa5e9687 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -81,7 +81,8 @@ impl <T: Ord> PriorityQueue<T> { /// Push an item onto the queue fn push(&mut self, item: T) { self.data.push(item); - self.siftup(0, self.len() - 1); + let new_len = self.len() - 1; + self.siftup(0, new_len); } /// Optimized version of a push followed by a pop @@ -179,7 +180,8 @@ impl <T: Ord> PriorityQueue<T> { } priv fn siftdown(&mut self, pos: uint) { - self.siftdown_range(pos, self.len()); + let len = self.len(); + self.siftdown_range(pos, len); } } diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 9642dd0c3dd..2e5cd8956cd 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -134,10 +134,11 @@ pub impl<V> SmallIntMap<V> { pub impl<V: Copy> SmallIntMap<V> { fn update_with_key(&mut self, key: uint, val: V, ff: fn(uint, V, V) -> V) -> bool { - match self.find(&key) { - None => self.insert(key, val), - Some(orig) => self.insert(key, ff(key, copy *orig, val)), - } + let new_val = match self.find(&key) { + None => val, + Some(orig) => ff(key, *orig, val) + }; + self.insert(key, new_val) } fn update(&mut self, key: uint, newval: V, ff: fn(V, V) -> V) -> bool { diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 26bf232adf5..2fdaeb545a2 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -673,45 +673,45 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool { } }; - if this { - *node = None; - return true; - } + if !this { + let left_level = save.left.map_default(0, |x| x.level); + let right_level = save.right.map_default(0, |x| x.level); - let left_level = save.left.map_default(0, |x| x.level); - let right_level = save.right.map_default(0, |x| x.level); + // re-balance, if necessary + if left_level < save.level - 1 || right_level < save.level - 1 { + save.level -= 1; - // re-balance, if necessary - if left_level < save.level - 1 || right_level < save.level - 1 { - save.level -= 1; + if right_level > save.level { + do save.right.mutate |mut x| { x.level = save.level; x } + } - if right_level > save.level { - do save.right.mutate |mut x| { x.level = save.level; x } - } + skew(save); - skew(save); + match save.right { + Some(ref mut right) => { + skew(right); + match right.right { + Some(ref mut x) => { skew(x) }, + None => () + } + } + None => () + } - match save.right { - Some(ref mut right) => { - skew(right); - match right.right { - Some(ref mut x) => { skew(x) }, - None => () + split(save); + match save.right { + Some(ref mut x) => { split(x) }, + None => () } - } - None => () } - split(save); - match save.right { - Some(ref mut x) => { split(x) }, - None => () - } + return removed; } - - removed } } + + *node = None; + return true; } #[cfg(test)] |
