[*] AuAsync build regression

[*] Fix potential for null deref under net adapters api
[*] Improved generic IO WaitFor * AND * (still suxs)
This commit is contained in:
Reece Wilson 2024-10-09 01:58:18 +01:00
parent f93181b0bf
commit 82ed6e5617
7 changed files with 152 additions and 68 deletions

View File

@ -703,6 +703,10 @@ namespace __detail
#endif
#endif
#if defined(AU_LANG_CPP_20) && !defined(AU_NO_COROUTINES)
#define AU_HasCoRoutineTraitsAvailable
#endif
#if defined(AU_NO_COROUTINES) || ((defined(AURORA_COMPILER_MSVC) && defined(AU_LANG_CPP_14)) || (defined(AURORA_COMPILER_CLANG) && defined(AU_LANG_CPP_14)) || (defined(AURORA_COMPILER_CLANG) && defined(AU_LANG_CPP_17)) || (defined(AURORA_COMPILER_MSVC) && !defined(_RESUMABLE_FUNCTIONS_SUPPORTED)))
#elif defined(AU_HasCoRoutinedIncluded)

View File

@ -134,6 +134,7 @@ namespace Aurora::IO::Loop
if (lsList.size() == 1)
{
AuUInt8 uFlags {};
auto pSource = lsList[0];
if (!pSource)
{
@ -141,18 +142,23 @@ namespace Aurora::IO::Loop
return true;
}
if (!bSpin)
{
uFlags = kFlagLSTryNoSpin;
}
bool bStatus {};
if (bSleepForever)
{
bStatus = pSource->WaitOn(0);
bStatus = pSource->WaitOnExt(uFlags, 0);
}
else if (bHasTimeOut)
{
bStatus = pSource->WaitOn(optTimeoutMS.value());
bStatus = pSource->WaitOnExt(uFlags, optTimeoutMS.value());
}
else
{
bStatus = pSource->IsSignaled();
bStatus = pSource->IsSignaledExt(uFlags);
}
if (bStatus)
@ -173,6 +179,8 @@ namespace Aurora::IO::Loop
if (!bAny)
{
AuUInt32 uStartingOffset { 1 };
auto &entryZero = lsList[0];
if (!entryZero)
@ -183,25 +191,32 @@ namespace Aurora::IO::Loop
if (entryZero)
{
bool bStatus {};
auto eType = entryZero->GetType();
AuUInt8 uFlags {};
if (bSleepForever)
if (!bSpin)
{
bStatus = entryZero->WaitOn(0);
uFlags = kFlagLSTryNoSpin;
}
if (eType == ELoopSource::eSourceMutex ||
eType == ELoopSource::eSourceFastMutex)
{
bStatus = false;
uStartingOffset = 0;
goto mainAllSleep;
}
else if (bSleepForever)
{
bStatus = entryZero->WaitOnExt(uFlags, 0);
}
else if (bHasTimeOut)
{
bStatus = entryZero->WaitOn(optTimeoutMS.value());
}
else if (bSpin)
{
bStatus = entryZero->IsSignaled();
bStatus = entryZero->WaitOnExt(uFlags, optTimeoutMS.value());
}
else
{
auto pSourceEx = AuDynamicCast<Loop::ILoopSourceEx>(entryZero);
bStatus = pSourceEx ?
pSourceEx->IsSignaledNoSpinIfUserland() :
entryZero->IsSignaled();
bStatus = entryZero->IsSignaledExt(uFlags);
}
if (!bStatus)
@ -215,66 +230,99 @@ namespace Aurora::IO::Loop
}
}
if (lsList.size() > 1 &&
mainAllSleep:
if (lsList.size() > uStartingOffset &&
(!bAvoidKrn || signaled.empty()))
{
for (AU_ITERATE_N_TO_X(i, 1, lsList.size()))
for (AU_ITERATE_N(a, 2))
{
AuUInt32 uTimeoutMS {};
bool dBreak {};
if (uTimeoutEnd)
for (AU_ITERATE_N_TO_X(i, uStartingOffset, lsList.size()))
{
auto uStartTime = Time::SteadyClockNS();
if (uStartTime >= uTimeoutEnd)
{
#if 0
break;
#else
bZeroTick = true;
#endif
}
AuUInt32 uTimeoutMS {};
bool bIsMutex {};
ELoopSource eType;
uTimeoutMS = AuNSToMS<AuInt64>(uTimeoutEnd - uStartTime);
if (!uTimeoutMS)
{
#if 0
break;
#else
bZeroTick = true;
#endif
}
}
auto &pCurrent = lsList[i];
if (bZeroTick)
{
if (bSpin)
eType = pCurrent->GetType();
bIsMutex = eType == ELoopSource::eSourceMutex ||
eType == ELoopSource::eSourceFastMutex;
if (bIsMutex ^ bool(a))
{
if (!lsList[i]->IsSignaled())
continue;
}
if (uTimeoutEnd && !bZeroTick)
{
auto uStartTime = Time::SteadyClockNS();
if (uStartTime >= uTimeoutEnd)
{
break;
bZeroTick = true;
}
uTimeoutMS = AuNSToMS<AuInt64>(uTimeoutEnd - uStartTime);
if (!uTimeoutMS)
{
bZeroTick = true;
}
}
if (bZeroTick)
{
if (bSpin)
{
if (!pCurrent->IsSignaled())
{
dBreak = true;
break;
}
bSpin = false;
}
else
{
if (!pCurrent->IsSignaledExt(kFlagLSTryNoSpin))
{
dBreak = true;
break;
}
}
}
else
{
auto pSourceEx = AuDynamicCast<Loop::ILoopSourceEx>(lsList[i]);
if (!(pSourceEx ?
pSourceEx->IsSignaledNoSpinIfUserland() :
entryZero->IsSignaled()))
if (bSpin)
{
break;
if (!pCurrent->WaitOnAbs(uTimeoutEnd))
{
dBreak = true;
break;
}
// TBD
bSpin = false;
}
else
{
if (!pCurrent->WaitOnAbsExt(kFlagLSTryNoSpin, uTimeoutEnd))
{
dBreak = true;
break;
}
}
}
}
else
{
if (!lsList[i]->WaitOn(uTimeoutMS))
{
break;
}
reverseList.push_back(i);
signaled.push_back(pCurrent);
}
reverseList.push_back(i);
signaled.push_back(lsList[i]);
if (dBreak || signaled.size() != lsList.size())
{
break;
}
}
}
@ -328,12 +376,9 @@ namespace Aurora::IO::Loop
eType == ELoopSource::eSourceFastSemaphore ||
eType == ELoopSource::eSourceFastEvent)
{
auto pSourceEx = AuDynamicCast<Loop::ILoopSourceEx>(pSource);
bAnyFound = true;
if ((pSourceEx && pSourceEx->IsSignaledNoSpinIfUserland()) ||
(!pSourceEx && pSource->IsSignaled()))
if (pSource->IsSignaledExt(kFlagLSTryNoSpin))
{
signalTemp.push_back(pSource);
itr = lsList2.erase(itr);

View File

@ -17,7 +17,7 @@ namespace Aurora::IO::Loop
bool WaitSingleBase::IsSignaled()
{
return this->IsSignaledExt(0);
return WaitSingleBase::IsSignaledExt(0);
}
bool WaitSingleBase::IsSignaledExt(AuUInt8 uFlags)
@ -75,7 +75,7 @@ namespace Aurora::IO::Loop
bool WaitSingleBase::WaitOn(AuUInt32 timeout)
{
return this->WaitOnExt(0, timeout);
return WaitSingleBase::WaitOnExt(0, timeout);
}
bool WaitSingleBase::WaitOnExt(AuUInt8 uFlags, AuUInt32 timeout)
@ -96,12 +96,12 @@ namespace Aurora::IO::Loop
AuTime::SteadyClockNS() + AuMSToNS<AuUInt64>(timeout) :
0;
return this->WaitOnAbsExt(uFlags, uEndTime);
return WaitSingleBase::WaitOnAbsExt(uFlags, uEndTime);
}
bool WaitSingleBase::WaitOnAbs(AuUInt64 uTimeoutAbs)
{
return this->WaitOnAbsExt(0, uTimeoutAbs);
return WaitSingleBase::WaitOnAbsExt(0, uTimeoutAbs);
}
bool WaitSingleBase::WaitOnAbsExt(AuUInt8 uFlags, AuUInt64 uEndTime)

View File

@ -239,9 +239,16 @@ namespace Aurora::IO::Net
adapter.uReceiveBytesPerSec = pCurrAddresses->ReceiveLinkSpeed / 8;
}
if (adapter.address.Value().ip == EIPProtocol::eIPProtocolV4)
if (adapter.address)
{
adapter.index = pCurrAddresses->IfIndex;
if (adapter.address.Value().ip == EIPProtocol::eIPProtocolV4)
{
adapter.index = pCurrAddresses->IfIndex;
}
else
{
adapter.index = adaptersOut.size();
}
}
else
{

View File

@ -63,6 +63,10 @@ namespace Aurora::IO::Net
AuSPtr<NetWorker> NetSrvWorkers::GetWorkerByIndex(AuUInt index)
{
AU_LOCK_GUARD(this->mutex_);
if (this->workerPool_.empty())
{
return {};
}
return this->workerPool_[index % this->workerPool_.size()];
}

View File

@ -180,7 +180,31 @@ namespace Aurora::Threading
{
if (releasedObjects[i])
{
waitables[i]->Unlock();
AuUInt uHandle(0);
if (!waitables[i]->HasOSHandle(uHandle) &&
uHandle == 0xFF69421)
{
// Autoreset events
// In 2020/2021, I didn't want semaphore and mutex behaviour in event iwaitable::unlock()
// The logic:
//
// AU_LOCK_GUARD(gMutex) makes sense
//
// Semaphore gSemaphore(1); // a mutex
// AU_LOCK_GUARD(gSemaphore) can make sense in academic theory only
//
// AU_LOCK_GUARD(gResetEvent) does not sense.
// in the condvar pattern, the signaling thread does the unlock.
//
// ...therefore, the ::Unlock() should not be event setters.
AuStaticCast<AuThreadPrimitives::IEvent>(waitables[i])->Set();
}
else
{
// Semaphores and Mutexes
waitables[i]->Unlock();
}
}
}
}

View File

@ -297,7 +297,7 @@ namespace Aurora::Threading::Primitives
bool EventImpl::HasOSHandle(AuMach &mach)
{
mach = 0;
mach = this->bAtomicRelease_ ? 0xFF69421 : 0;
return false;
}