Hold read lock during startup shrink (#17309)

* hold read lock during account scan of shrink

* rename and improve rusty
This commit is contained in:
Jeff Washington (jwash)
2021-05-21 13:59:32 -05:00
committed by GitHub
parent 96cde36784
commit 3f3324231d
2 changed files with 75 additions and 36 deletions

View File

@@ -838,10 +838,16 @@ impl<T: 'static + Clone + IsCached + ZeroLamport> AccountsIndex<T> {
}
pub fn get_account_read_entry(&self, pubkey: &Pubkey) -> Option<ReadAccountMapEntry<T>> {
self.account_maps
.read()
.unwrap()
.get(pubkey)
let lock = self.get_account_maps_read_lock();
self.get_account_read_entry_with_lock(pubkey, &lock)
}
pub fn get_account_read_entry_with_lock(
&self,
pubkey: &Pubkey,
lock: &AccountMapsReadLock<'_, T>,
) -> Option<ReadAccountMapEntry<T>> {
lock.get(pubkey)
.cloned()
.map(ReadAccountMapEntry::from_account_map_entry)
}
@@ -1184,6 +1190,10 @@ impl<T: 'static + Clone + IsCached + ZeroLamport> AccountsIndex<T> {
self.account_maps.write().unwrap()
}
pub(crate) fn get_account_maps_read_lock(&self) -> AccountMapsReadLock<T> {
self.account_maps.read().unwrap()
}
// Same functionally to upsert, but:
// 1. operates on a batch of items
// 2. holds the write lock for the duration of adding the items
@@ -2411,8 +2421,21 @@ pub mod tests {
}
assert!(gc.is_empty());
{
let entry = index.get_account_read_entry(&key).unwrap();
for lock in &[false, true] {
let read_lock = if *lock {
Some(index.get_account_maps_read_lock())
} else {
None
};
let entry = if *lock {
index
.get_account_read_entry_with_lock(&key, read_lock.as_ref().unwrap())
.unwrap()
} else {
index.get_account_read_entry(&key).unwrap()
};
assert_eq!(
entry.ref_count().load(Ordering::Relaxed),
if is_cached { 0 } else { 2 }