@@ -30,7 +30,7 @@ use ctypes::{BlockHash, BlockNumber, Header, TxHash};
3030use cvm:: ChainTimeInfo ;
3131use kvdb:: KeyValueDB ;
3232use parking_lot:: { Mutex , RwLock } ;
33- use primitives:: { Bytes , H256 } ;
33+ use primitives:: { Bytes , H256 , U256 } ;
3434
3535use super :: mem_pool:: { Error as MemPoolError , MemPool } ;
3636use 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+
132159struct SealingBlockLastRequest {
133160 block_number : Mutex < u64 > ,
134161}
@@ -201,7 +228,7 @@ impl Params {
201228impl 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