From 9956f1c153ba4a22e2f841a655fee98af9ecbdcf Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Tue, 30 Jul 2024 16:48:51 +0100 Subject: [PATCH] [+] AuIO::Loop::kWaitMultipleFlagBreakAfterOne for Win32 WaitForMultipleObjects shim (we cannot return an array of indices to a win32 program) --- Include/Aurora/IO/Loop/Loop.hpp | 7 +-- Source/IO/Loop/LSIOHandle.hpp | 2 +- Source/IO/Loop/Loop.NT.cpp | 21 +++++---- Source/IO/Loop/Loop.cpp | 76 ++++++++++++++++++++++++--------- 4 files changed, 74 insertions(+), 32 deletions(-) diff --git a/Include/Aurora/IO/Loop/Loop.hpp b/Include/Aurora/IO/Loop/Loop.hpp index d947f1ed..ea7a2ff9 100644 --- a/Include/Aurora/IO/Loop/Loop.hpp +++ b/Include/Aurora/IO/Loop/Loop.hpp @@ -27,9 +27,10 @@ namespace Aurora::IO::Loop bool bAny = { true }, AuOptional optTimeoutMS = {}); - static const AuUInt64 kWaitMultipleFlagAny = 1 << 0; - static const AuUInt64 kWaitMultipleFlagNoSpin = 1 << 1; - static const AuUInt64 kWaitMultipleFlagAvoidKern = 1 << 2; + static const AuUInt64 kWaitMultipleFlagAny = 1 << 0; + static const AuUInt64 kWaitMultipleFlagNoSpin = 1 << 1; + static const AuUInt64 kWaitMultipleFlagAvoidKern = 1 << 2; + static const AuUInt64 kWaitMultipleFlagBreakAfterOne = 1 << 3; AUKN_SYM bool WaitMultipleLoopSourcesEx(const AuList> &lsList, AuList> &signaled, diff --git a/Source/IO/Loop/LSIOHandle.hpp b/Source/IO/Loop/LSIOHandle.hpp index bcc98de1..ae839ed1 100644 --- a/Source/IO/Loop/LSIOHandle.hpp +++ b/Source/IO/Loop/LSIOHandle.hpp @@ -27,7 +27,7 @@ namespace Aurora::IO::Loop #endif virtual ELoopSource GetType() override; - protected: + //protected: AuSPtr pHandle; }; } \ No newline at end of file diff --git a/Source/IO/Loop/Loop.NT.cpp b/Source/IO/Loop/Loop.NT.cpp index a1feede4..469a76b9 100644 --- a/Source/IO/Loop/Loop.NT.cpp +++ b/Source/IO/Loop/Loop.NT.cpp @@ -12,7 +12,7 @@ namespace Aurora::IO::Loop { - AuList> WaitMultipleOrObjects(const AuList> &objects, bool bZeroTick, AuUInt32 dwTimeoutReq, bool &bTooMany) + AuList> WaitMultipleOrObjects(const AuList> &objects, bool bZeroTick, AuUInt32 dwTimeoutReq, bool bAllowOthers, bool &bTooMany) { bool isWinLoop; AuList> loopSourceExs; @@ -108,6 +108,17 @@ namespace Aurora::IO::Loop } } + if (isPump) + { + // msg loop queue for trigger + AuTryInsert(triggered, msgSource); + + if (!bAllowOthers) + { + error = true; + } + } + for (const auto &source : loopSourceExs) { if (!error) @@ -119,7 +130,7 @@ namespace Aurora::IO::Loop for (const auto &handle : source->GetHandles()) { if ((firstTriggered == handle) || - (WaitForSingleObject(reinterpret_cast(handle), 0) == WAIT_OBJECT_0)) + (bAllowOthers && WaitForSingleObject(reinterpret_cast(handle), 0) == WAIT_OBJECT_0)) { lastHandle = handle; wasTriggered = true; @@ -138,12 +149,6 @@ namespace Aurora::IO::Loop source->OnFinishSleep(); } - if (isPump) - { - // msg loop queue for trigger - AuTryInsert(triggered, msgSource); - } - return triggered; } } \ No newline at end of file diff --git a/Source/IO/Loop/Loop.cpp b/Source/IO/Loop/Loop.cpp index ba371ad4..a199602f 100644 --- a/Source/IO/Loop/Loop.cpp +++ b/Source/IO/Loop/Loop.cpp @@ -8,6 +8,7 @@ #include #include "Loop.hpp" #include "ILoopSourceEx.hpp" +#include "LSIOHandle.hpp" #include namespace Aurora::IO::Loop @@ -53,9 +54,9 @@ namespace Aurora::IO::Loop } #if defined(AURORA_IS_MODERNNT_DERIVED) - AuList> WaitMultipleOrObjects(const AuList> &objects, bool bZeroTick, AuUInt32 timeout, bool &bTooMany); + AuList> WaitMultipleOrObjects(const AuList> &objects, bool bZeroTick, AuUInt32 timeout, bool bAllowOthers, bool &bTooMany); #endif - AuList> WaitMultipleOrObjectsFallback(const AuList> &objects, AuUInt32 timeout, bool bZeroTick, bool &bTimeout); + AuList> WaitMultipleOrObjectsFallback(const AuList> &objects, AuUInt32 timeout, bool bZeroTick, bool bAllowOthers, bool &bTimeout); void ResetLoopSourceFalseAlarm(const AuSPtr &pLoopSource) { @@ -292,6 +293,12 @@ namespace Aurora::IO::Loop itr != lsList2.end(); ) { + if (signalTemp.size() && + uFlags & kWaitMultipleFlagBreakAfterOne) + { + break; + } + auto pSource = *itr; if (!pSource) { @@ -342,8 +349,13 @@ namespace Aurora::IO::Loop AuThreadPrimitives::DoTryIf([&]() { DoTheThing(false); - return lsList2.size() != lsList.size() || - !bAnyFound; + + if (!bAnyFound) + { + return true; + } + + return bool(signalTemp.size()); }); if (bAnyFound) @@ -356,7 +368,10 @@ namespace Aurora::IO::Loop DoTheThing(true); } - if (lsList2.size()) + bool bAllowOthers = !(uFlags & kWaitMultipleFlagBreakAfterOne); + + if (lsList2.size() && + (bAllowOthers || signalTemp.empty())) { bZeroTick |= bool(signalTemp.size()); AuUInt32 uTimeoutMS {}; @@ -381,7 +396,7 @@ namespace Aurora::IO::Loop if (AuBuild::kCurrentVendor == AuBuild::EVendor::eGenericMicrosoft && lsList2.size() < MAXIMUM_WAIT_OBJECTS) { - signaled = WaitMultipleOrObjects(lsList2, bZeroTick, uTimeoutMS, bTooMany); + signaled = WaitMultipleOrObjects(lsList2, bZeroTick, uTimeoutMS, bAllowOthers, bTooMany); bTimedout = uTimeoutEnd && uTimeoutMS && !bZeroTick ? Time::SteadyClockNS() >= uTimeoutEnd : false; @@ -394,7 +409,7 @@ namespace Aurora::IO::Loop if (bTooMany) { - signaled = WaitMultipleOrObjectsFallback(lsList2, uTimeoutMS, bZeroTick, bTimedout); + signaled = WaitMultipleOrObjectsFallback(lsList2, uTimeoutMS, bZeroTick, bAllowOthers, bTimedout); bTimedout &= !bZeroTick; } } @@ -412,7 +427,7 @@ namespace Aurora::IO::Loop } } - AuList> WaitMultipleOrObjectsFallback(const AuList> &objects, AuUInt32 timeout, bool bZeroTick, bool &bTimeout) + AuList> WaitMultipleOrObjectsFallback(const AuList> &objects, AuUInt32 timeout, bool bZeroTick, bool bAllowOthers, bool &bTimeout) { AuList> loopSourceExs; AuList> triggered; @@ -468,7 +483,6 @@ namespace Aurora::IO::Loop auto pListener = AuMakeSharedThrow([&](const AuSPtr &source) { - AU_DEBUG_MEMCRUNCH; triggered.push_back(source); return false; }); @@ -495,19 +509,21 @@ namespace Aurora::IO::Loop for (AU_ITERATE_N(i, loopSourceExs.size())) { auto pLoopSource = loopSourceExs[i]; - - if (std::find(triggered.begin(), triggered.end(), pLoopSource) == triggered.end()) - { - auto eType = pLoopSource->GetType(); - if (!bTimeout || - eType == ELoopSource::eSourceFastMutex || - eType == ELoopSource::eSourceFastSemaphore || - eType == ELoopSource::eSourceFastEvent) + if (bAllowOthers || triggered.empty()) + { + if (std::find(triggered.begin(), triggered.end(), pLoopSource) == triggered.end()) { - if (pLoopSource->IsSignaledNoSpinIfUserland()) + auto eType = pLoopSource->GetType(); + + if (eType == ELoopSource::eSourceFastMutex || + eType == ELoopSource::eSourceFastSemaphore || + eType == ELoopSource::eSourceFastEvent) { - triggered.push_back(pLoopSource); + if (pLoopSource->IsSignaledNoSpinIfUserland()) + { + triggered.push_back(pLoopSource); + } } } } @@ -515,7 +531,19 @@ namespace Aurora::IO::Loop pLoopSource->OnFinishSleep(); } - return triggered; + if (!bAllowOthers && triggered.size() > 1) + { + for (AU_ITERATE_N_TO_X(i, 1, triggered.size())) + { + ResetLoopSourceFalseAlarm(triggered[i]); + } + + return { triggered[0] }; + } + else + { + return triggered; + } } AUKN_SYM AuInt64 DbgLoopSourceToReadFd(AuSPtr pLoopSource) @@ -546,6 +574,14 @@ namespace Aurora::IO::Loop return -1; } + if (auto pIOHandle = AuDynamicCast(pLoopSource)) + { + return pIOHandle->pHandle->GetOSWriteHandleSafe().OrElse([&]() + { + return pIOHandle->pHandle->GetOSReadHandleSafe(); + }).ValueOr(AuUInt(-1)); + } + auto pSourceEx = AuDynamicCast(pLoopSource); if (!pSourceEx) {