Skip to content

Commit 89d9edd

Browse files
committed
Introduce Notifiers
Nrtofiers limits the lifetime of the inner lock.
1 parent 2d875b6 commit 89d9edd

File tree

1 file changed

+33
-8
lines changed

1 file changed

+33
-8
lines changed

core/src/miner/miner.rs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use ctypes::{BlockHash, BlockNumber, Header, TxHash};
3030
use cvm::ChainTimeInfo;
3131
use kvdb::KeyValueDB;
3232
use parking_lot::{Mutex, RwLock};
33-
use primitives::{Bytes, H256};
33+
use primitives::{Bytes, H256, U256};
3434

3535
use super::mem_pool::{Error as MemPoolError, MemPool};
3636
use super::mem_pool_types::{AccountDetails, MemPoolInput, TxOrigin, TxTimelock};
@@ -124,11 +124,38 @@ pub struct Miner {
124124
sealing_enabled: AtomicBool,
125125

126126
accounts: Option<Arc<AccountProvider>>,
127-
notifiers: RwLock<Vec<Box<dyn NotifyWork>>>,
127+
notifiers: Notifiers,
128128
malicious_users: RwLock<HashSet<Address>>,
129129
immune_users: RwLock<HashSet<Address>>,
130130
}
131131

132+
struct Notifiers {
133+
notifiers: RwLock<Vec<Box<dyn NotifyWork>>>,
134+
}
135+
136+
impl Notifiers {
137+
pub fn new(notifiers: Vec<Box<dyn NotifyWork>>) -> Self {
138+
Self {
139+
notifiers: RwLock::new(notifiers),
140+
}
141+
}
142+
143+
pub fn push(&self, notifier: Box<dyn NotifyWork>) {
144+
self.notifiers.write().push(notifier);
145+
}
146+
147+
pub fn is_empty(&self) -> bool {
148+
self.notifiers.read().is_empty()
149+
}
150+
151+
pub fn notify(&self, pow_hash: H256, target: U256) {
152+
// FIXME: Calling callbacks inside of lock lifetime may cause a deadlock.
153+
for notifier in self.notifiers.read().iter() {
154+
notifier.notify(pow_hash, target)
155+
}
156+
}
157+
}
158+
132159
struct SealingBlockLastRequest {
133160
block_number: Mutex<u64>,
134161
}
@@ -201,7 +228,7 @@ impl Params {
201228
impl Miner {
202229
/// Push listener that will handle new jobs
203230
pub fn add_work_listener(&self, notifier: Box<dyn NotifyWork>) {
204-
self.notifiers.write().push(notifier);
231+
self.notifiers.push(notifier);
205232
}
206233

207234
pub fn new(
@@ -251,7 +278,7 @@ impl Miner {
251278
options,
252279
sealing_enabled: AtomicBool::new(true),
253280
accounts,
254-
notifiers: RwLock::new(notifiers),
281+
notifiers: Notifiers::new(notifiers),
255282
malicious_users: RwLock::new(HashSet::new()),
256283
immune_users: RwLock::new(HashSet::new()),
257284
}
@@ -502,7 +529,7 @@ impl Miner {
502529
let is_new = original_work_hash.map_or(true, |h| *block.block().header().hash() != h);
503530
sealing_work.queue.push(block);
504531
// If push notifications are enabled we assume all work items are used.
505-
if !self.notifiers.read().is_empty() && is_new {
532+
if !self.notifiers.is_empty() && is_new {
506533
sealing_work.queue.use_last_ref();
507534
}
508535
(Some((pow_hash, score, number)), is_new)
@@ -519,9 +546,7 @@ impl Miner {
519546
if is_new {
520547
if let Some((pow_hash, score, _number)) = work {
521548
let target = self.engine.score_to_target(&score);
522-
for notifier in self.notifiers.read().iter() {
523-
notifier.notify(pow_hash, target)
524-
}
549+
self.notifiers.notify(pow_hash, target);
525550
}
526551
}
527552
}

0 commit comments

Comments
 (0)