@@ -38,6 +38,8 @@ use lightning::routing::router::Router;
38
38
use lightning:: routing:: scoring:: { Score , WriteableScore } ;
39
39
use lightning:: util:: logger:: Logger ;
40
40
use lightning:: util:: persist:: Persister ;
41
+ #[ cfg( feature = "std" ) ]
42
+ use lightning:: util:: wakers:: Sleeper ;
41
43
use lightning_rapid_gossip_sync:: RapidGossipSync ;
42
44
43
45
use core:: ops:: Deref ;
@@ -114,6 +116,13 @@ const FIRST_NETWORK_PRUNE_TIMER: u64 = 60;
114
116
#[ cfg( test) ]
115
117
const FIRST_NETWORK_PRUNE_TIMER : u64 = 1 ;
116
118
119
+ #[ cfg( feature = "futures" ) ]
120
+ /// core::cmp::min is not currently const, so we define a trivial (and equivalent) replacement
121
+ const fn min_u64 ( a : u64 , b : u64 ) -> u64 { if a < b { a } else { b } }
122
+ #[ cfg( feature = "futures" ) ]
123
+ const FASTEST_TIMER : u64 = min_u64 ( min_u64 ( FRESHNESS_TIMER , PING_TIMER ) ,
124
+ min_u64 ( SCORER_PERSIST_TIMER , FIRST_NETWORK_PRUNE_TIMER ) ) ;
125
+
117
126
/// Either [`P2PGossipSync`] or [`RapidGossipSync`].
118
127
pub enum GossipSync <
119
128
P : Deref < Target = P2PGossipSync < G , U , L > > ,
@@ -256,7 +265,8 @@ macro_rules! define_run_body {
256
265
( $persister: ident, $chain_monitor: ident, $process_chain_monitor_events: expr,
257
266
$channel_manager: ident, $process_channel_manager_events: expr,
258
267
$gossip_sync: ident, $peer_manager: ident, $logger: ident, $scorer: ident,
259
- $loop_exit_check: expr, $await: expr, $get_timer: expr, $timer_elapsed: expr)
268
+ $loop_exit_check: expr, $await: expr, $get_timer: expr, $timer_elapsed: expr,
269
+ $check_slow_await: expr)
260
270
=> { {
261
271
log_trace!( $logger, "Calling ChannelManager's timer_tick_occurred on startup" ) ;
262
272
$channel_manager. timer_tick_occurred( ) ;
@@ -286,9 +296,10 @@ macro_rules! define_run_body {
286
296
287
297
// We wait up to 100ms, but track how long it takes to detect being put to sleep,
288
298
// see `await_start`'s use below.
289
- let mut await_start = $get_timer( 1 ) ;
299
+ let mut await_start = None ;
300
+ if $check_slow_await { await_start = Some ( $get_timer( 1 ) ) ; }
290
301
let updates_available = $await;
291
- let await_slow = $ timer_elapsed( & mut await_start, 1 ) ;
302
+ let await_slow = if $check_slow_await { $ timer_elapsed( & mut await_start. unwrap ( ) , 1 ) } else { false } ;
292
303
293
304
if updates_available {
294
305
log_trace!( $logger, "Persisting ChannelManager..." ) ;
@@ -388,23 +399,32 @@ pub(crate) mod futures_util {
388
399
use core:: task:: { Poll , Waker , RawWaker , RawWakerVTable } ;
389
400
use core:: pin:: Pin ;
390
401
use core:: marker:: Unpin ;
391
- pub ( crate ) struct Selector < A : Future < Output =( ) > + Unpin , B : Future < Output =bool > + Unpin > {
402
+ pub ( crate ) struct Selector <
403
+ A : Future < Output =( ) > + Unpin , B : Future < Output =( ) > + Unpin , C : Future < Output =bool > + Unpin
404
+ > {
392
405
pub a : A ,
393
406
pub b : B ,
407
+ pub c : C ,
394
408
}
395
409
pub ( crate ) enum SelectorOutput {
396
- A , B ( bool ) ,
410
+ A , B , C ( bool ) ,
397
411
}
398
412
399
- impl < A : Future < Output =( ) > + Unpin , B : Future < Output =bool > + Unpin > Future for Selector < A , B > {
413
+ impl <
414
+ A : Future < Output =( ) > + Unpin , B : Future < Output =( ) > + Unpin , C : Future < Output =bool > + Unpin
415
+ > Future for Selector < A , B , C > {
400
416
type Output = SelectorOutput ;
401
417
fn poll ( mut self : Pin < & mut Self > , ctx : & mut core:: task:: Context < ' _ > ) -> Poll < SelectorOutput > {
402
418
match Pin :: new ( & mut self . a ) . poll ( ctx) {
403
419
Poll :: Ready ( ( ) ) => { return Poll :: Ready ( SelectorOutput :: A ) ; } ,
404
420
Poll :: Pending => { } ,
405
421
}
406
422
match Pin :: new ( & mut self . b ) . poll ( ctx) {
407
- Poll :: Ready ( res) => { return Poll :: Ready ( SelectorOutput :: B ( res) ) ; } ,
423
+ Poll :: Ready ( ( ) ) => { return Poll :: Ready ( SelectorOutput :: B ) ; } ,
424
+ Poll :: Pending => { } ,
425
+ }
426
+ match Pin :: new ( & mut self . c ) . poll ( ctx) {
427
+ Poll :: Ready ( res) => { return Poll :: Ready ( SelectorOutput :: C ( res) ) ; } ,
408
428
Poll :: Pending => { } ,
409
429
}
410
430
Poll :: Pending
@@ -438,6 +458,11 @@ use core::task;
438
458
/// feature, doing so will skip calling [`NetworkGraph::remove_stale_channels_and_tracking`],
439
459
/// you should call [`NetworkGraph::remove_stale_channels_and_tracking_with_time`] regularly
440
460
/// manually instead.
461
+ ///
462
+ /// The `mobile_interruptable_platform` flag should be set if we're currently running on a
463
+ /// mobile device, where we may need to check for interruption of the application regularly. If you
464
+ /// are unsure, you should set the flag, as the performance impact of it is minimal unless there
465
+ /// are hundreds or thousands of simultaneous process calls running.
441
466
#[ cfg( feature = "futures" ) ]
442
467
pub async fn process_events_async <
443
468
' a ,
@@ -473,7 +498,7 @@ pub async fn process_events_async<
473
498
> (
474
499
persister : PS , event_handler : EventHandler , chain_monitor : M , channel_manager : CM ,
475
500
gossip_sync : GossipSync < PGS , RGS , G , UL , L > , peer_manager : PM , logger : L , scorer : Option < S > ,
476
- sleeper : Sleeper ,
501
+ sleeper : Sleeper , mobile_interruptable_platform : bool ,
477
502
) -> Result < ( ) , lightning:: io:: Error >
478
503
where
479
504
UL :: Target : ' static + UtxoLookup ,
@@ -514,11 +539,13 @@ where
514
539
gossip_sync, peer_manager, logger, scorer, should_break, {
515
540
let fut = Selector {
516
541
a: channel_manager. get_persistable_update_future( ) ,
517
- b: sleeper( Duration :: from_millis( 100 ) ) ,
542
+ b: chain_monitor. get_update_future( ) ,
543
+ c: sleeper( if mobile_interruptable_platform { Duration :: from_millis( 100 ) } else { Duration :: from_secs( FASTEST_TIMER ) } ) ,
518
544
} ;
519
545
match fut. await {
520
546
SelectorOutput :: A => true ,
521
- SelectorOutput :: B ( exit) => {
547
+ SelectorOutput :: B => false ,
548
+ SelectorOutput :: C ( exit) => {
522
549
should_break = exit;
523
550
false
524
551
}
@@ -528,7 +555,7 @@ where
528
555
let mut waker = dummy_waker( ) ;
529
556
let mut ctx = task:: Context :: from_waker( & mut waker) ;
530
557
core:: pin:: Pin :: new( fut) . poll( & mut ctx) . is_ready( )
531
- } )
558
+ } , mobile_interruptable_platform )
532
559
}
533
560
534
561
#[ cfg( feature = "std" ) ]
@@ -643,8 +670,11 @@ impl BackgroundProcessor {
643
670
define_run_body ! ( persister, chain_monitor, chain_monitor. process_pending_events( & event_handler) ,
644
671
channel_manager, channel_manager. process_pending_events( & event_handler) ,
645
672
gossip_sync, peer_manager, logger, scorer, stop_thread. load( Ordering :: Acquire ) ,
646
- channel_manager. await_persistable_update_timeout( Duration :: from_millis( 100 ) ) ,
647
- |_| Instant :: now( ) , |time: & Instant , dur| time. elapsed( ) . as_secs( ) > dur)
673
+ Sleeper :: from_two_futures(
674
+ channel_manager. get_persistable_update_future( ) ,
675
+ chain_monitor. get_update_future( )
676
+ ) . wait_timeout( Duration :: from_millis( 100 ) ) ,
677
+ |_| Instant :: now( ) , |time: & Instant , dur| time. elapsed( ) . as_secs( ) > dur, false )
648
678
} ) ;
649
679
Self { stop_thread : stop_thread_clone, thread_handle : Some ( handle) }
650
680
}
0 commit comments