Fix potential undefined behavior (#13555)

* Switch to ouroboros 0.5.1

* Update other lock files
This commit is contained in:
joshua-maros 2020-11-13 01:12:41 -08:00 committed by GitHub
parent cbcde43765
commit a8a77614fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 40 deletions

8
Cargo.lock generated
View File

@ -2410,9 +2410,9 @@ dependencies = [
[[package]]
name = "ouroboros"
version = "0.4.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "776469997c56d7130b691a5edea1cbe63d7fef495f98b1b0ced0f3a5571c37aa"
checksum = "cc04551635026d3ac7bc646698ea1836a85ed2a26b7094fe1d15d8b14854c4a2"
dependencies = [
"ouroboros_macro",
"stable_deref_trait",
@ -2420,9 +2420,9 @@ dependencies = [
[[package]]
name = "ouroboros_macro"
version = "0.4.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85165ba45bb44e86ddb86e33ad92640522d572229c5c326eb7eb81ef31b06ce7"
checksum = "cec33dfceabec83cd0e95a5ce9d20e76ab3a5cbfef59659b8c927f69b93ed8ae"
dependencies = [
"Inflector",
"proc-macro2 1.0.24",

View File

@ -1259,9 +1259,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "ouroboros"
version = "0.4.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "776469997c56d7130b691a5edea1cbe63d7fef495f98b1b0ced0f3a5571c37aa"
checksum = "cc04551635026d3ac7bc646698ea1836a85ed2a26b7094fe1d15d8b14854c4a2"
dependencies = [
"ouroboros_macro",
"stable_deref_trait",
@ -1269,9 +1269,9 @@ dependencies = [
[[package]]
name = "ouroboros_macro"
version = "0.4.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85165ba45bb44e86ddb86e33ad92640522d572229c5c326eb7eb81ef31b06ce7"
checksum = "cec33dfceabec83cd0e95a5ce9d20e76ab3a5cbfef59659b8c927f69b93ed8ae"
dependencies = [
"Inflector",
"proc-macro2 1.0.24",

View File

@ -29,7 +29,7 @@ memmap = "0.7.0"
num-derive = { version = "0.3" }
num-traits = { version = "0.2" }
num_cpus = "1.13.0"
ouroboros = "0.4.0"
ouroboros = "0.5.1"
rand = "0.7.0"
rayon = "1.4.1"
regex = "1.3.9"

View File

@ -32,9 +32,9 @@ pub struct AccountMapEntryInner<T> {
#[self_referencing]
pub struct ReadAccountMapEntry<T: 'static> {
pub owned_entry: AccountMapEntry<T>,
owned_entry: AccountMapEntry<T>,
#[borrows(owned_entry)]
pub slot_list_guard: RwLockReadGuard<'this, SlotList<T>>,
slot_list_guard: RwLockReadGuard<'this, SlotList<T>>,
}
impl<T: Clone> ReadAccountMapEntry<T> {
@ -47,19 +47,19 @@ impl<T: Clone> ReadAccountMapEntry<T> {
}
pub fn slot_list(&self) -> &SlotList<T> {
&*self.slot_list_guard
&*self.borrow_slot_list_guard()
}
pub fn ref_count(&self) -> &AtomicU64 {
&self.owned_entry.ref_count
&self.borrow_owned_entry_contents().ref_count
}
}
#[self_referencing]
pub struct WriteAccountMapEntry<T: 'static> {
pub owned_entry: AccountMapEntry<T>,
owned_entry: AccountMapEntry<T>,
#[borrows(owned_entry)]
pub slot_list_guard: RwLockWriteGuard<'this, SlotList<T>>,
slot_list_guard: RwLockWriteGuard<'this, SlotList<T>>,
}
impl<T: 'static + Clone> WriteAccountMapEntry<T> {
@ -72,15 +72,18 @@ impl<T: 'static + Clone> WriteAccountMapEntry<T> {
}
pub fn slot_list(&mut self) -> &SlotList<T> {
&*self.slot_list_guard
&*self.borrow_slot_list_guard()
}
pub fn slot_list_mut(&mut self) -> &mut SlotList<T> {
&mut *self.slot_list_guard
pub fn slot_list_mut<RT>(
&mut self,
user: impl for<'this> FnOnce(&mut RwLockWriteGuard<'this, SlotList<T>>) -> RT,
) -> RT {
self.with_slot_list_guard_mut(user)
}
pub fn ref_count(&self) -> &AtomicU64 {
&self.owned_entry.ref_count
&self.borrow_owned_entry_contents().ref_count
}
// Try to update an item in the slot list the given `slot` If an item for the slot
@ -97,12 +100,12 @@ impl<T: 'static + Clone> WriteAccountMapEntry<T> {
assert!(same_slot_previous_updates.len() <= 1);
if let Some((list_index, (s, previous_update_value))) = same_slot_previous_updates.pop() {
reclaims.push((*s, previous_update_value.clone()));
self.slot_list_mut().remove(list_index);
self.slot_list_mut(|list| list.remove(list_index));
} else {
// Only increment ref count if the account was not prevously updated in this slot
self.ref_count().fetch_add(1, Ordering::Relaxed);
}
self.slot_list_mut().push((slot, account_info));
self.slot_list_mut(|list| list.push((slot, account_info)));
}
}
@ -301,22 +304,24 @@ impl<T: 'static + Clone> AccountsIndex<T> {
// if this account has no more entries.
pub fn purge(&self, pubkey: &Pubkey) -> (SlotList<T>, bool) {
let mut write_account_map_entry = self.get_account_write_entry(pubkey).unwrap();
let slot_list = write_account_map_entry.slot_list_mut();
let reclaims = self.get_rooted_entries(&slot_list);
slot_list.retain(|(slot, _)| !self.is_root(*slot));
(reclaims, slot_list.is_empty())
write_account_map_entry.slot_list_mut(|slot_list| {
let reclaims = self.get_rooted_entries(slot_list);
slot_list.retain(|(slot, _)| !self.is_root(*slot));
(reclaims, slot_list.is_empty())
})
}
pub fn purge_exact(&self, pubkey: &Pubkey, slots: HashSet<Slot>) -> (SlotList<T>, bool) {
let mut write_account_map_entry = self.get_account_write_entry(pubkey).unwrap();
let slot_list = write_account_map_entry.slot_list_mut();
let reclaims = slot_list
.iter()
.filter(|(slot, _)| slots.contains(&slot))
.cloned()
.collect();
slot_list.retain(|(slot, _)| !slots.contains(slot));
(reclaims, slot_list.is_empty())
write_account_map_entry.slot_list_mut(|slot_list| {
let reclaims = slot_list
.iter()
.filter(|(slot, _)| slots.contains(&slot))
.cloned()
.collect();
slot_list.retain(|(slot, _)| !slots.contains(slot));
(reclaims, slot_list.is_empty())
})
}
// Given a SlotSlice `L`, a list of ancestors and a maximum slot, find the latest element
@ -442,7 +447,9 @@ impl<T: 'static + Clone> AccountsIndex<T> {
max_clean_root: Option<Slot>,
) {
if let Some(mut locked_entry) = self.get_account_write_entry(pubkey) {
self.purge_older_root_entries(locked_entry.slot_list_mut(), reclaims, max_clean_root);
locked_entry.slot_list_mut(|slot_list| {
self.purge_older_root_entries(slot_list, reclaims, max_clean_root);
});
}
}
@ -453,12 +460,13 @@ impl<T: 'static + Clone> AccountsIndex<T> {
reclaims: &mut SlotList<T>,
) {
if let Some(mut locked_entry) = self.get_account_write_entry(pubkey) {
let slot_list = locked_entry.slot_list_mut();
slot_list.retain(|(slot, entry)| {
if *slot == purge_slot {
reclaims.push((*slot, entry.clone()));
}
*slot != purge_slot
locked_entry.slot_list_mut(|slot_list| {
slot_list.retain(|(slot, entry)| {
if *slot == purge_slot {
reclaims.push((*slot, entry.clone()));
}
*slot != purge_slot
});
});
}
}