1
- use crossbeam_channel:: { self as channel, after, select} ;
1
+ use bitcoin:: BlockHash ;
2
+ use crossbeam_channel:: { self as channel, after, select, Sender } ;
2
3
use std:: thread;
3
4
use std:: time:: { Duration , Instant } ;
4
5
@@ -9,6 +10,7 @@ use crate::errors::*;
9
10
#[ derive( Clone ) ] // so multiple threads could wait on signals
10
11
pub struct Waiter {
11
12
receiver : channel:: Receiver < i32 > ,
13
+ zmq_receiver : channel:: Receiver < BlockHash > ,
12
14
}
13
15
14
16
fn notify ( signals : & [ i32 ] ) -> channel:: Receiver < i32 > {
@@ -25,34 +27,54 @@ fn notify(signals: &[i32]) -> channel::Receiver<i32> {
25
27
}
26
28
27
29
impl Waiter {
28
- pub fn start ( ) -> Waiter {
29
- Waiter {
30
- receiver : notify ( & [
31
- SIGINT , SIGTERM ,
32
- SIGUSR1 , // allow external triggering (e.g. via bitcoind `blocknotify`)
33
- ] ) ,
34
- }
30
+ pub fn start ( ) -> ( Sender < BlockHash > , Waiter ) {
31
+ let ( block_hash_notify, block_hash_receive) = channel:: bounded ( 1 ) ;
32
+
33
+ (
34
+ block_hash_notify,
35
+ Waiter {
36
+ receiver : notify ( & [
37
+ SIGINT , SIGTERM ,
38
+ SIGUSR1 , // allow external triggering (e.g. via bitcoind `blocknotify`)
39
+ ] ) ,
40
+ zmq_receiver : block_hash_receive,
41
+ } ,
42
+ )
35
43
}
36
44
37
- pub fn wait ( & self , duration : Duration , accept_sigusr : bool ) -> Result < ( ) > {
45
+ pub fn wait ( & self , duration : Duration , accept_block_notification : bool ) -> Result < ( ) > {
38
46
let start = Instant :: now ( ) ;
39
47
select ! {
40
48
recv( self . receiver) -> msg => {
41
49
match msg {
42
50
Ok ( sig) if sig == SIGUSR1 => {
43
51
trace!( "notified via SIGUSR1" ) ;
44
- if accept_sigusr {
52
+ if accept_block_notification {
45
53
Ok ( ( ) )
46
54
} else {
47
55
let wait_more = duration. saturating_sub( start. elapsed( ) ) ;
48
- self . wait( wait_more, accept_sigusr )
56
+ self . wait( wait_more, accept_block_notification )
49
57
}
50
58
}
51
59
Ok ( sig) => bail!( ErrorKind :: Interrupt ( sig) ) ,
52
60
Err ( _) => bail!( "signal hook channel disconnected" ) ,
53
61
}
54
62
} ,
63
+ recv( self . zmq_receiver) -> msg => {
64
+ match msg {
65
+ Ok ( _) => {
66
+ if accept_block_notification {
67
+ Ok ( ( ) )
68
+ } else {
69
+ let wait_more = duration. saturating_sub( start. elapsed( ) ) ;
70
+ self . wait( wait_more, accept_block_notification)
71
+ }
72
+ }
73
+ Err ( _) => bail!( "signal hook channel disconnected" ) ,
74
+ }
75
+ } ,
55
76
recv( after( duration) ) -> _ => Ok ( ( ) ) ,
77
+
56
78
}
57
79
}
58
80
}
0 commit comments