runtime: fix possible deadlock in accounts_db (#10469)

This commit is contained in:
Boqin Qin 2020-06-10 18:37:15 +08:00 committed by GitHub
parent 75b8c2c4e3
commit 0a638a8f17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 19 additions and 7 deletions

View File

@ -42,7 +42,7 @@ use std::{
ops::RangeBounds,
path::{Path, PathBuf},
sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering},
sync::{Arc, Mutex, RwLock},
sync::{Arc, Mutex, RwLock, RwLockReadGuard},
time::Instant,
};
use tempfile::TempDir;
@ -964,10 +964,21 @@ impl AccountsDB {
F: Fn(&StoredAccount, AppendVecId, &mut B) + Send + Sync,
B: Send + Default,
{
let storage_maps: Vec<Arc<AccountStorageEntry>> = self
.storage
.read()
.unwrap()
self.scan_account_storage_inner(slot, scan_func, &self.storage.read().unwrap())
}
// The input storage must come from self.storage.read().unwrap()
fn scan_account_storage_inner<F, B>(
&self,
slot: Slot,
scan_func: F,
storage: &RwLockReadGuard<AccountStorage>,
) -> Vec<B>
where
F: Fn(&StoredAccount, AppendVecId, &mut B) + Send + Sync,
B: Send + Default,
{
let storage_maps: Vec<Arc<AccountStorageEntry>> = storage
.0
.get(&slot)
.unwrap_or(&HashMap::new())
@ -1806,10 +1817,10 @@ impl AccountsDB {
}
pub fn generate_index(&self) {
let mut accounts_index = self.accounts_index.write().unwrap();
let storage = self.storage.read().unwrap();
let mut slots: Vec<Slot> = storage.0.keys().cloned().collect();
slots.sort();
let mut accounts_index = self.accounts_index.write().unwrap();
let mut last_log_update = Instant::now();
for (index, slot) in slots.iter().enumerate() {
@ -1820,7 +1831,7 @@ impl AccountsDB {
}
let accumulator: Vec<HashMap<Pubkey, Vec<(u64, AccountInfo)>>> = self
.scan_account_storage(
.scan_account_storage_inner(
*slot,
|stored_account: &StoredAccount,
store_id: AppendVecId,
@ -1835,6 +1846,7 @@ impl AccountsDB {
.or_insert_with(Vec::new);
entry.push((stored_account.meta.write_version, account_info));
},
&storage,
);
let mut accounts_map: HashMap<Pubkey, Vec<(u64, AccountInfo)>> = HashMap::new();