IoUringAssmEngn: detect assembly end condition w/eventfdDesc validity

We can simplify and universalize the logic here by acknowledging that
assemblyCycleComplete() will always destroy the current eventfdDesc
object, so we can just check that to see whether we should continue
the assembly cycle.
This commit is contained in:
2025-11-15 22:02:30 -04:00
parent 8e48ce6ceb
commit b3743560bb
2 changed files with 13 additions and 14 deletions
@@ -309,7 +309,7 @@ void IoUringAssemblyEngine::assemblyCycleComplete()
{ {
// Cancel in-flight stall timeout timer // Cancel in-flight stall timeout timer
stallTimer.cancel(); stallTimer.cancel();
onCqeReadyCallback = std::move([](void *, int, bool&){}); onCqeReadyCallback = std::move([](void *, int){});
if (frameAssemblyDesc) if (frameAssemblyDesc)
{ {
@@ -441,8 +441,7 @@ public:
engine.resetAndAssembleFrame( engine.resetAndAssembleFrame(
std::bind(&AssembleFrameReq::assembleFrameReq2_2, std::bind(&AssembleFrameReq::assembleFrameReq2_2,
context.get(), context, context.get(), context,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_1, std::placeholders::_2));
std::placeholders::_3));
// Set up timeout timer for CONFIG_STIMBUFF_FRAME_PERIOD_MS/2 ms // Set up timeout timer for CONFIG_STIMBUFF_FRAME_PERIOD_MS/2 ms
engine.stallTimer.expires_from_now( engine.stallTimer.expires_from_now(
@@ -485,13 +484,12 @@ public:
// Set timer fired flag // Set timer fired flag
context->timerFired.store(true); context->timerFired.store(true);
bool dummyStopListening = false; // Timer path doesn't need this context->assembleFrameReq3(context);
context->assembleFrameReq3(context, dummyStopListening);
} }
void assembleFrameReq2_2( void assembleFrameReq2_2(
std::shared_ptr<AssembleFrameReq> context, std::shared_ptr<AssembleFrameReq> context,
void *user_data, int cqe_result, bool& stopListeningOnEventFd) void *user_data, int cqe_result)
{ {
// NB: The lock was acquired by onEventFdRead before calling this func // NB: The lock was acquired by onEventFdRead before calling this func
if (!context->engine.shouldAcceptRequests) if (!context->engine.shouldAcceptRequests)
@@ -515,13 +513,12 @@ public:
success)) success))
{ {
// Loop is complete, call oracle function // Loop is complete, call oracle function
context->assembleFrameReq3(context, stopListeningOnEventFd); context->assembleFrameReq3(context);
} }
} }
void assembleFrameReq3( void assembleFrameReq3(
std::shared_ptr<AssembleFrameReq> context, std::shared_ptr<AssembleFrameReq> context
bool& stopListeningOnEventFd
) )
{ {
/** EXPLANATION: /** EXPLANATION:
@@ -533,7 +530,6 @@ public:
if (context->handlerExecuted.exchange(true)) { return; } if (context->handlerExecuted.exchange(true)) { return; }
// Cancel the timer, stop the engine and process frame, if any. // Cancel the timer, stop the engine and process frame, if any.
context->engine.assemblyCycleComplete(); context->engine.assemblyCycleComplete();
stopListeningOnEventFd = true;
/** EXPLANATION: /** EXPLANATION:
* Timeout doesn't necessarily mean error. * Timeout doesn't necessarily mean error.
@@ -665,7 +661,6 @@ void IoUringAssemblyEngine::onEventfdRead(
*/ */
// Process all available CQEs and call callback for each one // Process all available CQEs and call callback for each one
bool stopListeningOnEventFd = false;
struct io_uring_cqe *cqe; struct io_uring_cqe *cqe;
while (io_uring_peek_cqe(&ring, &cqe) == 0) while (io_uring_peek_cqe(&ring, &cqe) == 0)
{ {
@@ -689,7 +684,7 @@ void IoUringAssemblyEngine::onEventfdRead(
* because of this. * because of this.
*/ */
if (onCqeReadyCallback) { if (onCqeReadyCallback) {
onCqeReadyCallback(user_data, cqe_result, stopListeningOnEventFd); onCqeReadyCallback(user_data, cqe_result);
} }
} }
@@ -697,7 +692,11 @@ void IoUringAssemblyEngine::onEventfdRead(
* But we do put a `return` here because we know that at this point, the * But we do put a `return` here because we know that at this point, the
* caller's callback has already been invoked. * caller's callback has already been invoked.
*/ */
if (!shouldAcceptRequests || stopListeningOnEventFd) { return; } if (!shouldAcceptRequests
|| eventfdDesc == nullptr || !eventfdDesc->is_open())
{
return;
}
// Re-arm the eventfd read for next CQE notification // Re-arm the eventfd read for next CQE notification
eventfdDesc->async_read_some( eventfdDesc->async_read_some(
@@ -47,7 +47,7 @@ public:
{ return nSucceeded != 0 && nTotal != 0 && nSucceeded != nTotal; } { return nSucceeded != 0 && nTotal != 0 && nSucceeded != nTotal; }
private: private:
typedef std::function<void(void*, int, bool&)> resetAndAssembleFrameCbFn; typedef std::function<void(void*, int)> resetAndAssembleFrameCbFn;
void resetAndAssembleFrame(resetAndAssembleFrameCbFn onCqeReady); void resetAndAssembleFrame(resetAndAssembleFrameCbFn onCqeReady);
void assemblyCycleComplete(); void assemblyCycleComplete();
bool stop(); bool stop();