@@ -30,7 +30,7 @@ use ctypes::{BlockHash, BlockNumber, Header, TxHash};
30
30
use cvm:: ChainTimeInfo ;
31
31
use kvdb:: KeyValueDB ;
32
32
use parking_lot:: { Mutex , RwLock } ;
33
- use primitives:: { Bytes , H256 } ;
33
+ use primitives:: { Bytes , H256 , U256 } ;
34
34
35
35
use super :: mem_pool:: { Error as MemPoolError , MemPool } ;
36
36
use super :: mem_pool_types:: { AccountDetails , MemPoolInput , TxOrigin , TxTimelock } ;
@@ -124,11 +124,38 @@ pub struct Miner {
124
124
sealing_enabled : AtomicBool ,
125
125
126
126
accounts : Option < Arc < AccountProvider > > ,
127
- notifiers : RwLock < Vec < Box < dyn NotifyWork > > > ,
127
+ notifiers : Notifiers ,
128
128
malicious_users : RwLock < HashSet < Address > > ,
129
129
immune_users : RwLock < HashSet < Address > > ,
130
130
}
131
131
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
+
132
159
struct SealingBlockLastRequest {
133
160
block_number : Mutex < u64 > ,
134
161
}
@@ -201,7 +228,7 @@ impl Params {
201
228
impl Miner {
202
229
/// Push listener that will handle new jobs
203
230
pub fn add_work_listener ( & self , notifier : Box < dyn NotifyWork > ) {
204
- self . notifiers . write ( ) . push ( notifier) ;
231
+ self . notifiers . push ( notifier) ;
205
232
}
206
233
207
234
pub fn new (
@@ -251,7 +278,7 @@ impl Miner {
251
278
options,
252
279
sealing_enabled : AtomicBool :: new ( true ) ,
253
280
accounts,
254
- notifiers : RwLock :: new ( notifiers) ,
281
+ notifiers : Notifiers :: new ( notifiers) ,
255
282
malicious_users : RwLock :: new ( HashSet :: new ( ) ) ,
256
283
immune_users : RwLock :: new ( HashSet :: new ( ) ) ,
257
284
}
@@ -502,7 +529,7 @@ impl Miner {
502
529
let is_new = original_work_hash. map_or ( true , |h| * block. block ( ) . header ( ) . hash ( ) != h) ;
503
530
sealing_work. queue . push ( block) ;
504
531
// 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 {
506
533
sealing_work. queue . use_last_ref ( ) ;
507
534
}
508
535
( Some ( ( pow_hash, score, number) ) , is_new)
@@ -519,9 +546,7 @@ impl Miner {
519
546
if is_new {
520
547
if let Some ( ( pow_hash, score, _number) ) = work {
521
548
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) ;
525
550
}
526
551
}
527
552
}
0 commit comments