Skip to content

Commit e54d8ab

Browse files
committed
Async: Do not complete multiple times requests waiting for teardown
1 parent cd423d1 commit e54d8ab

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

Libraries/Async/Async.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,9 @@ SC::Result SC::AsyncEventLoop::Internal::completeAndReactivateOrTeardown(AsyncEv
12621262
AsyncTeardown teardown;
12631263
prepareTeardown(eventLoop, async, teardown);
12641264
bool hasBeenReactivated = false;
1265+
async.flags |= Flag_NeedsTeardown;
12651266
SC_TRY(completeAsync(eventLoop, kernelEvents, async, eventIndex, returnCode, &hasBeenReactivated));
1267+
async.flags &= ~Flag_NeedsTeardown;
12661268
// hasBeenReactivated is required to avoid accessing async when it has been not reactivated (and maybe deallocated)
12671269
if (hasBeenReactivated and async.state == AsyncRequest::State::Reactivate)
12681270
{
@@ -1457,8 +1459,15 @@ void SC::AsyncEventLoop::Internal::runStepExecuteCompletions(AsyncEventLoop& eve
14571459
}
14581460
const int32_t eventIndex = static_cast<int32_t>(idx);
14591461

1460-
AsyncRequest& async = *request;
1461-
Result result = Result(kernelEvents.validateEvent(idx, continueProcessing));
1462+
AsyncRequest& async = *request;
1463+
if (async.flags & Flag_NeedsTeardown)
1464+
{
1465+
// runOnce has been called from a callback for this request on poll based API (kevent / epoll).
1466+
// As teardown for it has not been executed yet, the kernel will still signal this as writable
1467+
// or readable for this run too, but it would be incorrect to call its completion again.
1468+
continue;
1469+
}
1470+
Result result = Result(kernelEvents.validateEvent(idx, continueProcessing));
14621471
if (not result)
14631472
{
14641473
reportError(eventLoop, kernelEvents, async, result, eventIndex);

Libraries/Async/Internal/AsyncInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ struct SC::AsyncEventLoop::Internal
124124
static constexpr int16_t Flag_WatcherSet = 1 << 3; // An event watcher has been set
125125
static constexpr int16_t Flag_AsyncTaskSequence = 1 << 4; // AsyncRequest::sequence is an AsyncTaskSequence
126126
static constexpr int16_t Flag_AsyncTaskSequenceInUse = 1 << 5; // AsyncTaskSequence must still be waited
127+
static constexpr int16_t Flag_NeedsTeardown = 1 << 6; // Request being processed waiting for teardown
127128

128129
Result close(AsyncEventLoop& eventLoop);
129130

0 commit comments

Comments
 (0)