| 1212 | } |
| 1213 | |
| 1214 | SC::Result SC::AsyncEventLoopMonitor::stopMonitoringAndDispatchCompletions() |
| 1215 | { |
| 1216 | SC_TRY_MSG(eventLoop != nullptr, "Not initialized"); |
| 1217 | SC_TRY_MSG(not finished.load(), "Finished == true"); |
| 1218 | // Unblock the blocking poll on the other thread, even if it could be already unblocked |
| 1219 | const bool wakeUpMustBeSent = needsWakeUp.load(); |
| 1220 | if (wakeUpMustBeSent) |
| 1221 | { |
| 1222 | wakeUpHasBeenCalled = false; |
| 1223 | SC_TRY(eventLoopWakeUp.wakeUp(*eventLoop)); |
| 1224 | } |
| 1225 | eventObjectExitBlockingMode.wait(); |
| 1226 | needsWakeUp.exchange(true); |
| 1227 | // Dispatch the callbacks associated with the IO events signaled by AsyncEventLoop::blockingPoll |
| 1228 | SC_TRY(eventLoop->dispatchCompletions(asyncKernelEvents)); |
| 1229 | if (wakeUpMustBeSent and not wakeUpHasBeenCalled) |
| 1230 | { |
| 1231 | // We need one more event loop step to consume the earlier wakeUpFromExternalThread(). |
| 1232 | // Note: runOnce will also submit new async requests potentially queued by the callbacks. |
| 1233 | return eventLoop->runOnce(); |
| 1234 | } |
| 1235 | return Result(true); |
| 1236 | } |
| 1237 | |
| 1238 | SC::Result SC::AsyncEventLoopMonitor::close() |
| 1239 | { |
no test coverage detected