@@ -36,6 +36,7 @@ use crate::util::ser::Writeable;
36
36
37
37
use core:: fmt;
38
38
use core:: ops:: Deref ;
39
+ use core:: sync:: atomic:: { AtomicBool , Ordering } ;
39
40
use crate :: io;
40
41
use crate :: sync:: Mutex ;
41
42
use crate :: prelude:: * ;
@@ -262,6 +263,7 @@ pub struct OnionMessenger<
262
263
intercept_messages_for_offline_peers : bool ,
263
264
pending_intercepted_msgs_events : Mutex < Vec < Event > > ,
264
265
pending_peer_connected_events : Mutex < Vec < Event > > ,
266
+ pending_events_processor : AtomicBool ,
265
267
}
266
268
267
269
/// [`OnionMessage`]s buffered to be sent.
@@ -1004,6 +1006,28 @@ where
1004
1006
}
1005
1007
}
1006
1008
1009
+ macro_rules! drop_handled_events_and_abort { ( $self: expr, $res: expr, $offset: expr, $event_queue: expr) => {
1010
+ // We want ot make sure to cleanly abort upon event handling failure. To this end, we drop all
1011
+ // successfully handled events from the given queue, reset the events processing flag, and
1012
+ // return, to have the events eventually replayed upon next invocation.
1013
+ {
1014
+ let mut queue_lock = $event_queue. lock( ) . unwrap( ) ;
1015
+
1016
+ // We skip `$offset` result entries to reach the ones relevant for the given `$event_queue`.
1017
+ let mut res_iter = $res. iter( ) . skip( $offset) ;
1018
+
1019
+ // Keep all events which previously error'd *or* any that have been added since we dropped
1020
+ // the Mutex before.
1021
+ queue_lock. retain( |_| res_iter. next( ) . map_or( true , |r| r. is_err( ) ) ) ;
1022
+
1023
+ if $res. iter( ) . any( |r| r. is_err( ) ) {
1024
+ // We failed handling some events. Return to have them eventually replayed.
1025
+ $self. pending_events_processor. store( false , Ordering :: Release ) ;
1026
+ return ;
1027
+ }
1028
+ }
1029
+ } }
1030
+
1007
1031
impl < ES : Deref , NS : Deref , L : Deref , NL : Deref , MR : Deref , OMH : Deref , APH : Deref , CMH : Deref >
1008
1032
OnionMessenger < ES , NS , L , NL , MR , OMH , APH , CMH >
1009
1033
where
@@ -1080,6 +1104,7 @@ where
1080
1104
intercept_messages_for_offline_peers,
1081
1105
pending_intercepted_msgs_events : Mutex :: new ( Vec :: new ( ) ) ,
1082
1106
pending_peer_connected_events : Mutex :: new ( Vec :: new ( ) ) ,
1107
+ pending_events_processor : AtomicBool :: new ( false ) ,
1083
1108
}
1084
1109
}
1085
1110
@@ -1320,42 +1345,57 @@ where
1320
1345
pub async fn process_pending_events_async < Future : core:: future:: Future < Output = Result < ( ) , ReplayEvent > > + core:: marker:: Unpin , H : Fn ( Event ) -> Future > (
1321
1346
& self , handler : H
1322
1347
) {
1323
- let mut intercepted_msgs = Vec :: new ( ) ;
1324
- let mut peer_connecteds = Vec :: new ( ) ;
1325
- {
1326
- let mut pending_intercepted_msgs_events =
1327
- self . pending_intercepted_msgs_events . lock ( ) . unwrap ( ) ;
1328
- let mut pending_peer_connected_events =
1329
- self . pending_peer_connected_events . lock ( ) . unwrap ( ) ;
1330
- core:: mem:: swap ( & mut * pending_intercepted_msgs_events, & mut intercepted_msgs) ;
1331
- core:: mem:: swap ( & mut * pending_peer_connected_events, & mut peer_connecteds) ;
1348
+ if self . pending_events_processor . compare_exchange ( false , true , Ordering :: Acquire , Ordering :: Relaxed ) . is_err ( ) {
1349
+ return ;
1332
1350
}
1333
1351
1334
- let mut futures = Vec :: with_capacity ( intercepted_msgs. len ( ) ) ;
1335
- for ( node_id, recipient) in self . message_recipients . lock ( ) . unwrap ( ) . iter_mut ( ) {
1336
- if let OnionMessageRecipient :: PendingConnection ( _, addresses, _) = recipient {
1337
- if let Some ( addresses) = addresses. take ( ) {
1338
- futures. push ( handler ( Event :: ConnectionNeeded { node_id : * node_id, addresses } ) ) ;
1352
+ {
1353
+ let intercepted_msgs = self . pending_intercepted_msgs_events . lock ( ) . unwrap ( ) . clone ( ) ;
1354
+ let mut futures = Vec :: with_capacity ( intercepted_msgs. len ( ) ) ;
1355
+ for ( node_id, recipient) in self . message_recipients . lock ( ) . unwrap ( ) . iter_mut ( ) {
1356
+ if let OnionMessageRecipient :: PendingConnection ( _, addresses, _) = recipient {
1357
+ if let Some ( addresses) = addresses. take ( ) {
1358
+ futures. push ( handler ( Event :: ConnectionNeeded { node_id : * node_id, addresses } ) ) ;
1359
+ }
1339
1360
}
1340
1361
}
1341
- }
1342
1362
1343
- for ev in intercepted_msgs {
1344
- if let Event :: OnionMessageIntercepted { .. } = ev { } else { debug_assert ! ( false ) ; }
1345
- futures. push ( handler ( ev) ) ;
1363
+ // The offset in the `futures` vec at which `intercepted_msgs` start. We don't bother
1364
+ // replaying `ConnectionNeeded` events.
1365
+ let intercepted_msgs_offset = futures. len ( ) ;
1366
+
1367
+ for ev in intercepted_msgs {
1368
+ if let Event :: OnionMessageIntercepted { .. } = ev { } else { debug_assert ! ( false ) ; }
1369
+ futures. push ( handler ( ev) ) ;
1370
+ }
1371
+ // Let the `OnionMessageIntercepted` events finish before moving on to peer_connecteds
1372
+ let res = crate :: util:: async_poll:: MultiEventFuturePoller :: new ( futures) . await ;
1373
+ drop_handled_events_and_abort ! ( self , res, intercepted_msgs_offset, self . pending_intercepted_msgs_events) ;
1346
1374
}
1347
- // Let the `OnionMessageIntercepted` events finish before moving on to peer_connecteds
1348
- crate :: util:: async_poll:: MultiEventFuturePoller :: new ( futures) . await ;
1349
1375
1350
- if peer_connecteds. len ( ) <= 1 {
1351
- for event in peer_connecteds { handler ( event) . await ; }
1352
- } else {
1353
- let mut futures = Vec :: new ( ) ;
1354
- for event in peer_connecteds {
1355
- futures. push ( handler ( event) ) ;
1376
+ {
1377
+ let peer_connecteds = self . pending_peer_connected_events . lock ( ) . unwrap ( ) . clone ( ) ;
1378
+ let num_peer_connecteds = peer_connecteds. len ( ) ;
1379
+ if num_peer_connecteds <= 1 {
1380
+ for event in peer_connecteds {
1381
+ if handler ( event) . await . is_ok ( ) {
1382
+ self . pending_peer_connected_events . lock ( ) . unwrap ( ) . drain ( ..num_peer_connecteds) ;
1383
+ } else {
1384
+ // We failed handling the event. Return to have it eventually replayed.
1385
+ self . pending_events_processor . store ( false , Ordering :: Release ) ;
1386
+ return ;
1387
+ }
1388
+ }
1389
+ } else {
1390
+ let mut futures = Vec :: new ( ) ;
1391
+ for event in peer_connecteds {
1392
+ futures. push ( handler ( event) ) ;
1393
+ }
1394
+ let res = crate :: util:: async_poll:: MultiEventFuturePoller :: new ( futures) . await ;
1395
+ drop_handled_events_and_abort ! ( self , res, 0 , self . pending_peer_connected_events) ;
1356
1396
}
1357
- crate :: util:: async_poll:: MultiEventFuturePoller :: new ( futures) . await ;
1358
1397
}
1398
+ self . pending_events_processor . store ( false , Ordering :: Release ) ;
1359
1399
}
1360
1400
}
1361
1401
@@ -1395,17 +1435,24 @@ where
1395
1435
CMH :: Target : CustomOnionMessageHandler ,
1396
1436
{
1397
1437
fn process_pending_events < H : Deref > ( & self , handler : H ) where H :: Target : EventHandler {
1438
+ if self . pending_events_processor . compare_exchange ( false , true , Ordering :: Acquire , Ordering :: Relaxed ) . is_err ( ) {
1439
+ return ;
1440
+ }
1441
+
1398
1442
for ( node_id, recipient) in self . message_recipients . lock ( ) . unwrap ( ) . iter_mut ( ) {
1399
1443
if let OnionMessageRecipient :: PendingConnection ( _, addresses, _) = recipient {
1400
1444
if let Some ( addresses) = addresses. take ( ) {
1401
1445
handler. handle_event ( Event :: ConnectionNeeded { node_id : * node_id, addresses } ) . ok ( ) ;
1402
1446
}
1403
1447
}
1404
1448
}
1405
- let mut events = Vec :: new ( ) ;
1449
+ let intercepted_msgs;
1450
+ let peer_connecteds;
1406
1451
{
1407
- let mut pending_intercepted_msgs_events = self . pending_intercepted_msgs_events . lock ( ) . unwrap ( ) ;
1452
+ let pending_intercepted_msgs_events = self . pending_intercepted_msgs_events . lock ( ) . unwrap ( ) ;
1453
+ intercepted_msgs = pending_intercepted_msgs_events. clone ( ) ;
1408
1454
let mut pending_peer_connected_events = self . pending_peer_connected_events . lock ( ) . unwrap ( ) ;
1455
+ peer_connecteds = pending_peer_connected_events. clone ( ) ;
1409
1456
#[ cfg( debug_assertions) ] {
1410
1457
for ev in pending_intercepted_msgs_events. iter ( ) {
1411
1458
if let Event :: OnionMessageIntercepted { .. } = ev { } else { panic ! ( ) ; }
@@ -1414,13 +1461,16 @@ where
1414
1461
if let Event :: OnionMessagePeerConnected { .. } = ev { } else { panic ! ( ) ; }
1415
1462
}
1416
1463
}
1417
- core:: mem:: swap ( & mut * pending_intercepted_msgs_events, & mut events) ;
1418
- events. append ( & mut pending_peer_connected_events) ;
1419
1464
pending_peer_connected_events. shrink_to ( 10 ) ; // Limit total heap usage
1420
1465
}
1421
- for ev in events {
1422
- handler. handle_event ( ev) ;
1423
- }
1466
+
1467
+ let res = intercepted_msgs. into_iter ( ) . map ( |ev| handler. handle_event ( ev) ) . collect :: < Vec < _ > > ( ) ;
1468
+ drop_handled_events_and_abort ! ( self , res, 0 , self . pending_intercepted_msgs_events) ;
1469
+
1470
+ let res = peer_connecteds. into_iter ( ) . map ( |ev| handler. handle_event ( ev) ) . collect :: < Vec < _ > > ( ) ;
1471
+ drop_handled_events_and_abort ! ( self , res, 0 , self . pending_peer_connected_events) ;
1472
+
1473
+ self . pending_events_processor . store ( false , Ordering :: Release ) ;
1424
1474
}
1425
1475
}
1426
1476
0 commit comments