[+] 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

@ -27,9 +27,10 @@ namespace Aurora::IO::Loop
bool bAny = { true },
AuOptional<AuUInt32> 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<AuSPtr<Loop::ILoopSource>> &lsList,
AuList<AuSPtr<Loop::ILoopSource>> &signaled,

View File

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

View File

@ -12,7 +12,7 @@
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;
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)
{
if (!error)
@ -119,7 +130,7 @@ namespace Aurora::IO::Loop
for (const auto &handle : source->GetHandles())
{
if ((firstTriggered == handle) ||
(WaitForSingleObject(reinterpret_cast<HANDLE>(handle), 0) == WAIT_OBJECT_0))
(bAllowOthers && WaitForSingleObject(reinterpret_cast<HANDLE>(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;
}
}

View File

@ -8,6 +8,7 @@
#include <Source/RuntimeInternal.hpp>
#include "Loop.hpp"
#include "ILoopSourceEx.hpp"
#include "LSIOHandle.hpp"
#include <Source/Threading/Primitives/SMTYield.hpp>
namespace Aurora::IO::Loop
@ -53,9 +54,9 @@ namespace Aurora::IO::Loop
}
#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
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)
{
@ -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<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<ILoopSource>> triggered;
@ -468,7 +483,6 @@ namespace Aurora::IO::Loop
auto pListener = AuMakeSharedThrow<AuLoop::ILoopSourceSubscriberFunctional>([&](const AuSPtr<ILoopSource> &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<ILoopSource> pLoopSource)
@ -546,6 +574,14 @@ namespace Aurora::IO::Loop
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);
if (!pSourceEx)
{