runtime: fix possible deadlock in accounts_db (#10469)
This commit is contained in:
parent
75b8c2c4e3
commit
0a638a8f17
|
@ -42,7 +42,7 @@ use std::{
|
||||||
ops::RangeBounds,
|
ops::RangeBounds,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering},
|
sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering},
|
||||||
sync::{Arc, Mutex, RwLock},
|
sync::{Arc, Mutex, RwLock, RwLockReadGuard},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
@ -964,10 +964,21 @@ impl AccountsDB {
|
||||||
F: Fn(&StoredAccount, AppendVecId, &mut B) + Send + Sync,
|
F: Fn(&StoredAccount, AppendVecId, &mut B) + Send + Sync,
|
||||||
B: Send + Default,
|
B: Send + Default,
|
||||||
{
|
{
|
||||||
let storage_maps: Vec<Arc<AccountStorageEntry>> = self
|
self.scan_account_storage_inner(slot, scan_func, &self.storage.read().unwrap())
|
||||||
.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
|
.0
|
||||||
.get(&slot)
|
.get(&slot)
|
||||||
.unwrap_or(&HashMap::new())
|
.unwrap_or(&HashMap::new())
|
||||||
|
@ -1806,10 +1817,10 @@ impl AccountsDB {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_index(&self) {
|
pub fn generate_index(&self) {
|
||||||
|
let mut accounts_index = self.accounts_index.write().unwrap();
|
||||||
let storage = self.storage.read().unwrap();
|
let storage = self.storage.read().unwrap();
|
||||||
let mut slots: Vec<Slot> = storage.0.keys().cloned().collect();
|
let mut slots: Vec<Slot> = storage.0.keys().cloned().collect();
|
||||||
slots.sort();
|
slots.sort();
|
||||||
let mut accounts_index = self.accounts_index.write().unwrap();
|
|
||||||
|
|
||||||
let mut last_log_update = Instant::now();
|
let mut last_log_update = Instant::now();
|
||||||
for (index, slot) in slots.iter().enumerate() {
|
for (index, slot) in slots.iter().enumerate() {
|
||||||
|
@ -1820,7 +1831,7 @@ impl AccountsDB {
|
||||||
}
|
}
|
||||||
|
|
||||||
let accumulator: Vec<HashMap<Pubkey, Vec<(u64, AccountInfo)>>> = self
|
let accumulator: Vec<HashMap<Pubkey, Vec<(u64, AccountInfo)>>> = self
|
||||||
.scan_account_storage(
|
.scan_account_storage_inner(
|
||||||
*slot,
|
*slot,
|
||||||
|stored_account: &StoredAccount,
|
|stored_account: &StoredAccount,
|
||||||
store_id: AppendVecId,
|
store_id: AppendVecId,
|
||||||
|
@ -1835,6 +1846,7 @@ impl AccountsDB {
|
||||||
.or_insert_with(Vec::new);
|
.or_insert_with(Vec::new);
|
||||||
entry.push((stored_account.meta.write_version, account_info));
|
entry.push((stored_account.meta.write_version, account_info));
|
||||||
},
|
},
|
||||||
|
&storage,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut accounts_map: HashMap<Pubkey, Vec<(u64, AccountInfo)>> = HashMap::new();
|
let mut accounts_map: HashMap<Pubkey, Vec<(u64, AccountInfo)>> = HashMap::new();
|
||||||
|
|
Loading…
Reference in New Issue