@@ -39,7 +39,7 @@ use ctypes::{BlockHash, BlockNumber, Header, TxHash};
3939use cvm:: ChainTimeInfo ;
4040use kvdb:: KeyValueDB ;
4141use parking_lot:: { Mutex , RwLock } ;
42- use primitives:: { Bytes , H256 } ;
42+ use primitives:: { Bytes , H256 , U256 } ;
4343use std:: borrow:: Borrow ;
4444use std:: collections:: HashSet ;
4545use std:: iter:: once;
@@ -126,11 +126,38 @@ pub struct Miner {
126126 sealing_enabled : AtomicBool ,
127127
128128 accounts : Option < Arc < AccountProvider > > ,
129- notifiers : RwLock < Vec < Box < dyn NotifyWork > > > ,
129+ notifiers : Notifiers ,
130130 malicious_users : RwLock < HashSet < Address > > ,
131131 immune_users : RwLock < HashSet < Address > > ,
132132}
133133
134+ struct Notifiers {
135+ notifiers : RwLock < Vec < Box < dyn NotifyWork > > > ,
136+ }
137+
138+ impl Notifiers {
139+ pub fn new ( notifiers : Vec < Box < dyn NotifyWork > > ) -> Self {
140+ Self {
141+ notifiers : RwLock :: new ( notifiers) ,
142+ }
143+ }
144+
145+ pub fn push ( & self , notifier : Box < dyn NotifyWork > ) {
146+ self . notifiers . write ( ) . push ( notifier) ;
147+ }
148+
149+ pub fn is_empty ( & self ) -> bool {
150+ self . notifiers . read ( ) . is_empty ( )
151+ }
152+
153+ pub fn notify ( & self , pow_hash : H256 , target : U256 ) {
154+ // FIXME: Calling callbacks inside of lock lifetime may cause a deadlock.
155+ for notifier in self . notifiers . read ( ) . iter ( ) {
156+ notifier. notify ( pow_hash, target)
157+ }
158+ }
159+ }
160+
134161struct SealingBlockLastRequest {
135162 block_number : Mutex < u64 > ,
136163}
@@ -203,7 +230,7 @@ impl Params {
203230impl Miner {
204231 /// Push listener that will handle new jobs
205232 pub fn add_work_listener ( & self , notifier : Box < dyn NotifyWork > ) {
206- self . notifiers . write ( ) . push ( notifier) ;
233+ self . notifiers . push ( notifier) ;
207234 }
208235
209236 pub fn new (
@@ -254,7 +281,7 @@ impl Miner {
254281 options,
255282 sealing_enabled : AtomicBool :: new ( true ) ,
256283 accounts,
257- notifiers : RwLock :: new ( notifiers) ,
284+ notifiers : Notifiers :: new ( notifiers) ,
258285 malicious_users : RwLock :: new ( HashSet :: new ( ) ) ,
259286 immune_users : RwLock :: new ( HashSet :: new ( ) ) ,
260287 }
@@ -503,7 +530,7 @@ impl Miner {
503530 let is_new = original_work_hash. map_or ( true , |h| * block. block ( ) . header ( ) . hash ( ) != h) ;
504531 sealing_work. queue . push ( block) ;
505532 // If push notifications are enabled we assume all work items are used.
506- if !self . notifiers . read ( ) . is_empty ( ) && is_new {
533+ if !self . notifiers . is_empty ( ) && is_new {
507534 sealing_work. queue . use_last_ref ( ) ;
508535 }
509536 ( Some ( ( pow_hash, score, number) ) , is_new)
@@ -520,9 +547,7 @@ impl Miner {
520547 if is_new {
521548 if let Some ( ( pow_hash, score, _number) ) = work {
522549 let target = self . engine . score_to_target ( & score) ;
523- for notifier in self . notifiers . read ( ) . iter ( ) {
524- notifier. notify ( pow_hash, target)
525- }
550+ self . notifiers . notify ( pow_hash, target) ;
526551 }
527552 }
528553 }
0 commit comments