[+] AuIO::Loop::kWaitMultipleFlagBreakAfterOne for Win32 WaitForMultipleObjects shim (we cannot return an array of indices to a win32 program)

This commit is contained in:
Reece Wilson 2024-07-30 16:48:51 +01:00
parent ecf8dc6f0b
commit 9956f1c153
4 changed files with 74 additions and 32 deletions

View File

@ -30,6 +30,7 @@ namespace Aurora::IO::Loop
static const AuUInt64 kWaitMultipleFlagAny = 1 << 0; static const AuUInt64 kWaitMultipleFlagAny = 1 << 0;
static const AuUInt64 kWaitMultipleFlagNoSpin = 1 << 1; static const AuUInt64 kWaitMultipleFlagNoSpin = 1 << 1;
static const AuUInt64 kWaitMultipleFlagAvoidKern = 1 << 2; static const AuUInt64 kWaitMultipleFlagAvoidKern = 1 << 2;
static const AuUInt64 kWaitMultipleFlagBreakAfterOne = 1 << 3;
AUKN_SYM bool WaitMultipleLoopSourcesEx(const AuList<AuSPtr<Loop::ILoopSource>> &lsList, AUKN_SYM bool WaitMultipleLoopSourcesEx(const AuList<AuSPtr<Loop::ILoopSource>> &lsList,
AuList<AuSPtr<Loop::ILoopSource>> &signaled, AuList<AuSPtr<Loop::ILoopSource>> &signaled,

View File

@ -27,7 +27,7 @@ namespace Aurora::IO::Loop
#endif #endif
virtual ELoopSource GetType() override; virtual ELoopSource GetType() override;
protected: //protected:
AuSPtr<IIOHandle> pHandle; AuSPtr<IIOHandle> pHandle;
}; };
} }

View File

@ -12,7 +12,7 @@
namespace Aurora::IO::Loop namespace Aurora::IO::Loop
{ {
AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjects(const AuList<AuSPtr<ILoopSource>> &objects, bool bZeroTick, AuUInt32 dwTimeoutReq, bool &bTooMany) AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjects(const AuList<AuSPtr<ILoopSource>> &objects, bool bZeroTick, AuUInt32 dwTimeoutReq, bool bAllowOthers, bool &bTooMany)
{ {
bool isWinLoop; bool isWinLoop;
AuList<AuSPtr<ILoopSourceEx>> loopSourceExs; AuList<AuSPtr<ILoopSourceEx>> 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) for (const auto &source : loopSourceExs)
{ {
if (!error) if (!error)
@ -119,7 +130,7 @@ namespace Aurora::IO::Loop
for (const auto &handle : source->GetHandles()) for (const auto &handle : source->GetHandles())
{ {
if ((firstTriggered == handle) || if ((firstTriggered == handle) ||
(WaitForSingleObject(reinterpret_cast<HANDLE>(handle), 0) == WAIT_OBJECT_0)) (bAllowOthers && WaitForSingleObject(reinterpret_cast<HANDLE>(handle), 0) == WAIT_OBJECT_0))
{ {
lastHandle = handle; lastHandle = handle;
wasTriggered = true; wasTriggered = true;
@ -138,12 +149,6 @@ namespace Aurora::IO::Loop
source->OnFinishSleep(); source->OnFinishSleep();
} }
if (isPump)
{
// msg loop queue for trigger
AuTryInsert(triggered, msgSource);
}
return triggered; return triggered;
} }
} }

View File

@ -8,6 +8,7 @@
#include <Source/RuntimeInternal.hpp> #include <Source/RuntimeInternal.hpp>
#include "Loop.hpp" #include "Loop.hpp"
#include "ILoopSourceEx.hpp" #include "ILoopSourceEx.hpp"
#include "LSIOHandle.hpp"
#include <Source/Threading/Primitives/SMTYield.hpp> #include <Source/Threading/Primitives/SMTYield.hpp>
namespace Aurora::IO::Loop namespace Aurora::IO::Loop
@ -53,9 +54,9 @@ namespace Aurora::IO::Loop
} }
#if defined(AURORA_IS_MODERNNT_DERIVED) #if defined(AURORA_IS_MODERNNT_DERIVED)
AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjects(const AuList<AuSPtr<ILoopSource>> &objects, bool bZeroTick, AuUInt32 timeout, bool &bTooMany); AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjects(const AuList<AuSPtr<ILoopSource>> &objects, bool bZeroTick, AuUInt32 timeout, bool bAllowOthers, bool &bTooMany);
#endif #endif
AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjectsFallback(const AuList<AuSPtr<ILoopSource>> &objects, AuUInt32 timeout, bool bZeroTick, bool &bTimeout); AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjectsFallback(const AuList<AuSPtr<ILoopSource>> &objects, AuUInt32 timeout, bool bZeroTick, bool bAllowOthers, bool &bTimeout);
void ResetLoopSourceFalseAlarm(const AuSPtr<Loop::ILoopSource> &pLoopSource) void ResetLoopSourceFalseAlarm(const AuSPtr<Loop::ILoopSource> &pLoopSource)
{ {
@ -292,6 +293,12 @@ namespace Aurora::IO::Loop
itr != lsList2.end(); itr != lsList2.end();
) )
{ {
if (signalTemp.size() &&
uFlags & kWaitMultipleFlagBreakAfterOne)
{
break;
}
auto pSource = *itr; auto pSource = *itr;
if (!pSource) if (!pSource)
{ {
@ -342,8 +349,13 @@ namespace Aurora::IO::Loop
AuThreadPrimitives::DoTryIf([&]() AuThreadPrimitives::DoTryIf([&]()
{ {
DoTheThing(false); DoTheThing(false);
return lsList2.size() != lsList.size() ||
!bAnyFound; if (!bAnyFound)
{
return true;
}
return bool(signalTemp.size());
}); });
if (bAnyFound) if (bAnyFound)
@ -356,7 +368,10 @@ namespace Aurora::IO::Loop
DoTheThing(true); DoTheThing(true);
} }
if (lsList2.size()) bool bAllowOthers = !(uFlags & kWaitMultipleFlagBreakAfterOne);
if (lsList2.size() &&
(bAllowOthers || signalTemp.empty()))
{ {
bZeroTick |= bool(signalTemp.size()); bZeroTick |= bool(signalTemp.size());
AuUInt32 uTimeoutMS {}; AuUInt32 uTimeoutMS {};
@ -381,7 +396,7 @@ namespace Aurora::IO::Loop
if (AuBuild::kCurrentVendor == AuBuild::EVendor::eGenericMicrosoft && if (AuBuild::kCurrentVendor == AuBuild::EVendor::eGenericMicrosoft &&
lsList2.size() < MAXIMUM_WAIT_OBJECTS) lsList2.size() < MAXIMUM_WAIT_OBJECTS)
{ {
signaled = WaitMultipleOrObjects(lsList2, bZeroTick, uTimeoutMS, bTooMany); signaled = WaitMultipleOrObjects(lsList2, bZeroTick, uTimeoutMS, bAllowOthers, bTooMany);
bTimedout = uTimeoutEnd && uTimeoutMS && !bZeroTick ? bTimedout = uTimeoutEnd && uTimeoutMS && !bZeroTick ?
Time::SteadyClockNS() >= uTimeoutEnd : Time::SteadyClockNS() >= uTimeoutEnd :
false; false;
@ -394,7 +409,7 @@ namespace Aurora::IO::Loop
if (bTooMany) if (bTooMany)
{ {
signaled = WaitMultipleOrObjectsFallback(lsList2, uTimeoutMS, bZeroTick, bTimedout); signaled = WaitMultipleOrObjectsFallback(lsList2, uTimeoutMS, bZeroTick, bAllowOthers, bTimedout);
bTimedout &= !bZeroTick; bTimedout &= !bZeroTick;
} }
} }
@ -412,7 +427,7 @@ namespace Aurora::IO::Loop
} }
} }
AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjectsFallback(const AuList<AuSPtr<ILoopSource>> &objects, AuUInt32 timeout, bool bZeroTick, bool &bTimeout) AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjectsFallback(const AuList<AuSPtr<ILoopSource>> &objects, AuUInt32 timeout, bool bZeroTick, bool bAllowOthers, bool &bTimeout)
{ {
AuList<AuSPtr<ILoopSourceEx>> loopSourceExs; AuList<AuSPtr<ILoopSourceEx>> loopSourceExs;
AuList<AuSPtr<ILoopSource>> triggered; AuList<AuSPtr<ILoopSource>> triggered;
@ -468,7 +483,6 @@ namespace Aurora::IO::Loop
auto pListener = AuMakeSharedThrow<AuLoop::ILoopSourceSubscriberFunctional>([&](const AuSPtr<ILoopSource> &source) auto pListener = AuMakeSharedThrow<AuLoop::ILoopSourceSubscriberFunctional>([&](const AuSPtr<ILoopSource> &source)
{ {
AU_DEBUG_MEMCRUNCH;
triggered.push_back(source); triggered.push_back(source);
return false; return false;
}); });
@ -496,12 +510,13 @@ namespace Aurora::IO::Loop
{ {
auto pLoopSource = loopSourceExs[i]; auto pLoopSource = loopSourceExs[i];
if (bAllowOthers || triggered.empty())
{
if (std::find(triggered.begin(), triggered.end(), pLoopSource) == triggered.end()) if (std::find(triggered.begin(), triggered.end(), pLoopSource) == triggered.end())
{ {
auto eType = pLoopSource->GetType(); auto eType = pLoopSource->GetType();
if (!bTimeout || if (eType == ELoopSource::eSourceFastMutex ||
eType == ELoopSource::eSourceFastMutex ||
eType == ELoopSource::eSourceFastSemaphore || eType == ELoopSource::eSourceFastSemaphore ||
eType == ELoopSource::eSourceFastEvent) eType == ELoopSource::eSourceFastEvent)
{ {
@ -511,12 +526,25 @@ namespace Aurora::IO::Loop
} }
} }
} }
}
pLoopSource->OnFinishSleep(); pLoopSource->OnFinishSleep();
} }
if (!bAllowOthers && triggered.size() > 1)
{
for (AU_ITERATE_N_TO_X(i, 1, triggered.size()))
{
ResetLoopSourceFalseAlarm(triggered[i]);
}
return { triggered[0] };
}
else
{
return triggered; return triggered;
} }
}
AUKN_SYM AuInt64 DbgLoopSourceToReadFd(AuSPtr<ILoopSource> pLoopSource) AUKN_SYM AuInt64 DbgLoopSourceToReadFd(AuSPtr<ILoopSource> pLoopSource)
{ {
@ -546,6 +574,14 @@ namespace Aurora::IO::Loop
return -1; return -1;
} }
if (auto pIOHandle = AuDynamicCast<Loop::LSIOHandle>(pLoopSource))
{
return pIOHandle->pHandle->GetOSWriteHandleSafe().OrElse([&]()
{
return pIOHandle->pHandle->GetOSReadHandleSafe();
}).ValueOr(AuUInt(-1));
}
auto pSourceEx = AuDynamicCast<Loop::ILoopSourceEx>(pLoopSource); auto pSourceEx = AuDynamicCast<Loop::ILoopSourceEx>(pLoopSource);
if (!pSourceEx) if (!pSourceEx)
{ {