| 2303 | } |
| 2304 | |
| 2305 | void SC::AsyncEventLoop::Internal::executeWakeUps(AsyncEventLoop& eventLoop) |
| 2306 | { |
| 2307 | // Release the shared wake-up latch before dispatching callbacks so an external thread that requests another |
| 2308 | // wake-up during callback execution can enqueue a fresh kernel notification instead of being coalesced away. |
| 2309 | wakeUpPending.exchange(false); |
| 2310 | |
| 2311 | AsyncLoopWakeUp* async = activeLoopWakeUps.front; |
| 2312 | while (async != nullptr) |
| 2313 | { |
| 2314 | SC_ASYNC_ASSERT_DEBUG(async->type == AsyncRequest::Type::LoopWakeUp); |
| 2315 | AsyncLoopWakeUp* current = async; |
| 2316 | async = static_cast<AsyncLoopWakeUp*>(async->next); |
| 2317 | |
| 2318 | const int32_t deliveryCount = current->consumePendingWakeUps(); |
| 2319 | if (deliveryCount > 0) |
| 2320 | { |
| 2321 | bool hasBeenReactivated = false; |
| 2322 | Result res(true); |
| 2323 | AsyncLoopWakeUp::Result result(eventLoop, *current, res, &hasBeenReactivated); |
| 2324 | result.completionData.deliveryCount = static_cast<uint32_t>(deliveryCount); |
| 2325 | removeActiveHandle(*current); |
| 2326 | current->callback(result); |
| 2327 | if (current->eventObject) |
| 2328 | { |
| 2329 | current->eventObject->signal(); |
| 2330 | } |
| 2331 | if (hasBeenReactivated and current->getPendingWakeUps() > 0) |
| 2332 | { |
| 2333 | SC_ASYNC_ASSERT_RELEASE(eventLoop.wakeUpFromExternalThread()); |
| 2334 | } |
| 2335 | } |
| 2336 | } |
| 2337 | } |
| 2338 | |
| 2339 | void SC::AsyncEventLoop::Internal::removeActiveHandle(AsyncRequest& async) |
| 2340 | { |
nothing calls this directly
no test coverage detected