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
stallTimer.cancel();
onCqeReadyCallback = std::move([](void *, int, bool&){});
onCqeReadyCallback = std::move([](void *, int){});
if (frameAssemblyDesc)
{
@@ -441,8 +441,7 @@ public:
engine.resetAndAssembleFrame(
std::bind(&AssembleFrameReq::assembleFrameReq2_2,
context.get(), context,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
std::placeholders::_1, std::placeholders::_2));
// Set up timeout timer for CONFIG_STIMBUFF_FRAME_PERIOD_MS/2 ms
engine.stallTimer.expires_from_now(
@@ -485,13 +484,12 @@ public:
// Set timer fired flag
context->timerFired.store(true);
bool dummyStopListening = false; // Timer path doesn't need this
context->assembleFrameReq3(context, dummyStopListening);
context->assembleFrameReq3(context);
}
void assembleFrameReq2_2(
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
if (!context->engine.shouldAcceptRequests)
@@ -515,13 +513,12 @@ public:
success))
{
// Loop is complete, call oracle function
context->assembleFrameReq3(context, stopListeningOnEventFd);
context->assembleFrameReq3(context);
}
}
void assembleFrameReq3(
std::shared_ptr<AssembleFrameReq> context,
bool& stopListeningOnEventFd
std::shared_ptr<AssembleFrameReq> context
)
{
/** EXPLANATION:
@@ -533,7 +530,6 @@ public:
if (context->handlerExecuted.exchange(true)) { return; }
// Cancel the timer, stop the engine and process frame, if any.
context->engine.assemblyCycleComplete();
stopListeningOnEventFd = true;
/** EXPLANATION:
* Timeout doesn't necessarily mean error.
@@ -665,7 +661,6 @@ void IoUringAssemblyEngine::onEventfdRead(
*/
// Process all available CQEs and call callback for each one
bool stopListeningOnEventFd = false;
struct io_uring_cqe *cqe;
while (io_uring_peek_cqe(&ring, &cqe) == 0)
{
@@ -689,7 +684,7 @@ void IoUringAssemblyEngine::onEventfdRead(
* because of this.
*/
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
* 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
eventfdDesc->async_read_some(
@@ -47,7 +47,7 @@ public:
{ return nSucceeded != 0 && nTotal != 0 && nSucceeded != nTotal; }
private:
typedef std::function<void(void*, int, bool&)> resetAndAssembleFrameCbFn;
typedef std::function<void(void*, int)> resetAndAssembleFrameCbFn;
void resetAndAssembleFrame(resetAndAssembleFrameCbFn onCqeReady);
void assemblyCycleComplete();
bool stop();