Skip to content

Commit 2e11360

Browse files
committed
stock/MultiStock: prevent entering FinishWaiting() recursively
1 parent acc0c4f commit 2e11360

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

src/stock/MultiStock.cxx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ MultiStock::MapItem::~MapItem() noexcept
340340
{
341341
assert(items.empty());
342342
assert(waiting.empty());
343+
assert(!in_finish_waiting);
343344

344345
if (get_cancel_ptr)
345346
get_cancel_ptr.Cancel();
@@ -513,6 +514,7 @@ MultiStock::MapItem::FinishWaiting(OuterItem &item) noexcept
513514
assert(item.CanUse());
514515
assert(!waiting.empty());
515516
assert(!retry_event.IsPending());
517+
assert(!in_finish_waiting);
516518

517519
auto &w = waiting.pop_front();
518520
auto &get_handler = w.handler;
@@ -527,6 +529,8 @@ MultiStock::MapItem::FinishWaiting(OuterItem &item) noexcept
527529
really needed */
528530
DeleteEmptyItems(&item);
529531

532+
in_finish_waiting = true;
533+
530534
if (item.GetLease(inner_class, get_handler)) {
531535
if (!w.is_create) {
532536
++counters.successful_waits;
@@ -541,6 +545,8 @@ MultiStock::MapItem::FinishWaiting(OuterItem &item) noexcept
541545
waiting.push_front(w);
542546
retry_event.Cancel();
543547
}
548+
549+
in_finish_waiting = false;
544550
}
545551

546552
inline void
@@ -589,6 +595,13 @@ MultiStock::MapItem::OnStockItemReady(StockItem &stock_item) noexcept
589595
item for future use */
590596
return;
591597

598+
if (in_finish_waiting) {
599+
/* this was called from within FinishWaiting();
600+
instead of calling it again, defer the call */
601+
retry_event.Schedule();
602+
return;
603+
}
604+
592605
FinishWaiting(*item);
593606
}
594607

src/stock/MultiStock.hxx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,13 @@ class MultiStock {
247247
*/
248248
bool continue_on_cancel = false;
249249

250+
/**
251+
* Are we currently inside FinishWaiting()? This flag
252+
* prevents entering the method again through
253+
* OnStockItemReady().
254+
*/
255+
bool in_finish_waiting = false;
256+
250257
public:
251258
/**
252259
* For MultiStock::chronological_list.

0 commit comments

Comments
 (0)