Fixing locks order (#1328)

This commit is contained in:
Tomasz Drwięga 2016-06-19 12:33:50 +02:00 committed by Gav Wood
parent 3617923d3c
commit 8fad728e9b

View File

@ -31,13 +31,14 @@ use miner::{MinerService, MinerStatus, TransactionQueue, AccountDetails, Transac
/// Keeps track of transactions using priority queue and holds currently mined block. /// Keeps track of transactions using priority queue and holds currently mined block.
pub struct Miner { pub struct Miner {
// NOTE [ToDr] When locking always lock in this order!
transaction_queue: Mutex<TransactionQueue>, transaction_queue: Mutex<TransactionQueue>,
sealing_work: Mutex<UsingQueue<ClosedBlock>>,
// for sealing... // for sealing...
force_sealing: bool, force_sealing: bool,
sealing_enabled: AtomicBool, sealing_enabled: AtomicBool,
sealing_block_last_request: Mutex<u64>, sealing_block_last_request: Mutex<u64>,
sealing_work: Mutex<UsingQueue<ClosedBlock>>,
gas_floor_target: RwLock<U256>, gas_floor_target: RwLock<U256>,
author: RwLock<Address>, author: RwLock<Address>,
extra_data: RwLock<Bytes>, extra_data: RwLock<Bytes>,
@ -424,20 +425,20 @@ impl MinerService for Miner {
} }
fn pending_transactions_hashes(&self) -> Vec<H256> { fn pending_transactions_hashes(&self) -> Vec<H256> {
let queue = self.transaction_queue.lock().unwrap();
match (self.sealing_enabled.load(atomic::Ordering::Relaxed), self.sealing_work.lock().unwrap().peek_last_ref()) { match (self.sealing_enabled.load(atomic::Ordering::Relaxed), self.sealing_work.lock().unwrap().peek_last_ref()) {
(true, Some(pending)) => pending.transactions().iter().map(|t| t.hash()).collect(), (true, Some(pending)) => pending.transactions().iter().map(|t| t.hash()).collect(),
_ => { _ => {
let queue = self.transaction_queue.lock().unwrap();
queue.pending_hashes() queue.pending_hashes()
} }
} }
} }
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> { fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
let queue = self.transaction_queue.lock().unwrap();
match (self.sealing_enabled.load(atomic::Ordering::Relaxed), self.sealing_work.lock().unwrap().peek_last_ref()) { match (self.sealing_enabled.load(atomic::Ordering::Relaxed), self.sealing_work.lock().unwrap().peek_last_ref()) {
(true, Some(pending)) => pending.transactions().iter().find(|t| &t.hash() == hash).cloned(), (true, Some(pending)) => pending.transactions().iter().find(|t| &t.hash() == hash).cloned(),
_ => { _ => {
let queue = self.transaction_queue.lock().unwrap();
queue.find(hash) queue.find(hash)
} }
} }
@ -449,11 +450,11 @@ impl MinerService for Miner {
} }
fn pending_transactions(&self) -> Vec<SignedTransaction> { fn pending_transactions(&self) -> Vec<SignedTransaction> {
let queue = self.transaction_queue.lock().unwrap();
// TODO: should only use the sealing_work when it's current (it could be an old block) // TODO: should only use the sealing_work when it's current (it could be an old block)
match (self.sealing_enabled.load(atomic::Ordering::Relaxed), self.sealing_work.lock().unwrap().peek_last_ref()) { match (self.sealing_enabled.load(atomic::Ordering::Relaxed), self.sealing_work.lock().unwrap().peek_last_ref()) {
(true, Some(pending)) => pending.transactions().clone(), (true, Some(pending)) => pending.transactions().clone(),
_ => { _ => {
let queue = self.transaction_queue.lock().unwrap();
queue.top_transactions() queue.top_transactions()
} }
} }