@@ -270,7 +270,7 @@ isDuplicateTx(TransactionFrameBasePtr oldTx, TransactionFrameBasePtr newTx)
270
270
bool
271
271
TransactionQueue::sourceAccountPending (AccountID const & accountID) const
272
272
{
273
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
273
+ TxQueueLock guard = lock ( );
274
274
return mAccountStates .find (accountID) != mAccountStates .end ();
275
275
}
276
276
@@ -328,6 +328,22 @@ validateSorobanMemo(TransactionFrameBasePtr tx)
328
328
return true ;
329
329
}
330
330
331
+ TransactionQueue::TxQueueLock
332
+ TransactionQueue::lock () const
333
+ {
334
+ if (threadIsMain ())
335
+ {
336
+ mMainThreadWaiting .store (true );
337
+ std::unique_lock<std::mutex> lock (mTxQueueMutex );
338
+ mMainThreadWaiting .store (false );
339
+ return TxQueueLock (std::move (lock), mTxQueueCv );
340
+ }
341
+ std::unique_lock<std::mutex> lock (mTxQueueMutex );
342
+ mTxQueueCv ->wait (lock, [this ] { return !mMainThreadWaiting .load (); });
343
+ return TxQueueLock (std::move (lock), mTxQueueCv );
344
+ }
345
+
346
+
331
347
TransactionQueue::AddResult
332
348
TransactionQueue::canAdd (
333
349
TransactionFrameBasePtr tx, AccountStates::iterator& stateIter,
@@ -641,7 +657,7 @@ TransactionQueue::AddResult
641
657
TransactionQueue::tryAdd (TransactionFrameBasePtr tx, bool submittedFromSelf)
642
658
{
643
659
ZoneScoped;
644
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
660
+ TxQueueLock guard = lock ( );
645
661
CLOG_DEBUG (Tx, " Try add tx {} in {}" , hexAbbrev (tx->getFullHash ()),
646
662
threadIsMain () ? " foreground" : " background" );
647
663
818
834
TransactionQueue::ban (Transactions const & banTxs)
819
835
{
820
836
ZoneScoped;
821
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
837
+ TxQueueLock guard = lock ( );
822
838
banInternal (banTxs);
823
839
}
824
840
@@ -871,7 +887,7 @@ TransactionQueue::AccountState
871
887
TransactionQueue::getAccountTransactionQueueInfo (
872
888
AccountID const & accountID) const
873
889
{
874
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
890
+ TxQueueLock guard = lock ( );
875
891
auto i = mAccountStates .find (accountID);
876
892
if (i == std::end (mAccountStates ))
877
893
{
@@ -883,7 +899,7 @@ TransactionQueue::getAccountTransactionQueueInfo(
883
899
size_t
884
900
TransactionQueue::countBanned (int index) const
885
901
{
886
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
902
+ TxQueueLock guard = lock ( );
887
903
return mBannedTransactions [index ].size ();
888
904
}
889
905
#endif
@@ -958,7 +974,7 @@ TransactionQueue::shift()
958
974
bool
959
975
TransactionQueue::isBanned (Hash const & hash) const
960
976
{
961
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
977
+ TxQueueLock guard = lock ( );
962
978
return isBannedInternal (hash);
963
979
}
964
980
@@ -976,7 +992,7 @@ TxFrameList
976
992
TransactionQueue::getTransactions (LedgerHeader const & lcl) const
977
993
{
978
994
ZoneScoped;
979
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
995
+ TxQueueLock guard = lock ( );
980
996
return getTransactionsInternal (lcl);
981
997
}
982
998
@@ -1004,7 +1020,7 @@ TransactionFrameBaseConstPtr
1004
1020
TransactionQueue::getTx (Hash const & hash) const
1005
1021
{
1006
1022
ZoneScoped;
1007
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
1023
+ TxQueueLock guard = lock ( );
1008
1024
auto it = mKnownTxHashes .find (hash);
1009
1025
if (it != mKnownTxHashes .end ())
1010
1026
{
@@ -1223,7 +1239,7 @@ size_t
1223
1239
SorobanTransactionQueue::getMaxQueueSizeOps () const
1224
1240
{
1225
1241
ZoneScoped;
1226
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
1242
+ TxQueueLock guard = lock ( );
1227
1243
if (protocolVersionStartsFrom (
1228
1244
mBucketSnapshot ->getLedgerHeader ().ledgerVersion ,
1229
1245
SOROBAN_PROTOCOL_VERSION))
@@ -1317,8 +1333,7 @@ ClassicTransactionQueue::broadcastSome()
1317
1333
}
1318
1334
1319
1335
void
1320
- TransactionQueue::broadcast (bool fromCallback,
1321
- std::lock_guard<std::mutex> const & guard)
1336
+ TransactionQueue::broadcast (bool fromCallback, TxQueueLock const & guard)
1322
1337
{
1323
1338
// Must be called from the main thread due to the use of `mBroadcastTimer`
1324
1339
releaseAssert (threadIsMain ());
@@ -1357,12 +1372,12 @@ TransactionQueue::broadcast(bool fromCallback,
1357
1372
void
1358
1373
TransactionQueue::broadcast (bool fromCallback)
1359
1374
{
1360
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
1375
+ TxQueueLock guard = lock ( );
1361
1376
broadcast (fromCallback, guard);
1362
1377
}
1363
1378
1364
1379
void
1365
- TransactionQueue::rebroadcast (std::lock_guard<std::mutex> const & guard)
1380
+ TransactionQueue::rebroadcast (TxQueueLock const & guard)
1366
1381
{
1367
1382
// For `broadcast` call
1368
1383
releaseAssert (threadIsMain ());
@@ -1383,7 +1398,7 @@ void
1383
1398
TransactionQueue::shutdown ()
1384
1399
{
1385
1400
releaseAssert (threadIsMain ());
1386
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
1401
+ TxQueueLock guard = lock ( );
1387
1402
mShutdown = true ;
1388
1403
mBroadcastTimer .cancel ();
1389
1404
}
@@ -1396,7 +1411,7 @@ TransactionQueue::update(
1396
1411
{
1397
1412
ZoneScoped;
1398
1413
releaseAssert (threadIsMain ());
1399
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
1414
+ TxQueueLock guard = lock ( );
1400
1415
1401
1416
mValidationSnapshot =
1402
1417
std::make_shared<ImmutableValidationSnapshot>(mAppConn );
@@ -1455,7 +1470,7 @@ void
1455
1470
TransactionQueue::updateSnapshots (
1456
1471
SearchableSnapshotConstPtr const & newBucketSnapshot)
1457
1472
{
1458
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
1473
+ TxQueueLock guard = lock ( );
1459
1474
mValidationSnapshot =
1460
1475
std::make_shared<ImmutableValidationSnapshot>(mAppConn );
1461
1476
mBucketSnapshot = newBucketSnapshot;
@@ -1465,14 +1480,14 @@ TransactionQueue::updateSnapshots(
1465
1480
size_t
1466
1481
TransactionQueue::getQueueSizeOps () const
1467
1482
{
1468
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
1483
+ TxQueueLock guard = lock ( );
1469
1484
return mTxQueueLimiter .size ();
1470
1485
}
1471
1486
1472
1487
std::optional<int64_t >
1473
1488
TransactionQueue::getInQueueSeqNum (AccountID const & account) const
1474
1489
{
1475
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
1490
+ TxQueueLock guard = lock ( );
1476
1491
auto stateIter = mAccountStates .find (account);
1477
1492
if (stateIter == mAccountStates .end ())
1478
1493
{
@@ -1490,7 +1505,7 @@ size_t
1490
1505
ClassicTransactionQueue::getMaxQueueSizeOps () const
1491
1506
{
1492
1507
ZoneScoped;
1493
- std::lock_guard<std::mutex> guard ( mTxQueueMutex );
1508
+ TxQueueLock guard = lock ( );
1494
1509
auto res = mTxQueueLimiter .maxScaledLedgerResources (false );
1495
1510
releaseAssert (res.size () == NUM_CLASSIC_TX_RESOURCES);
1496
1511
return res.getVal (Resource::Type::OPERATIONS);
0 commit comments