[+] ILoopSource::IsSignaledExt(...)
[+] ILoopSource::WaitOnExt(...) [+] ILoopSource::WaitOnAbsExt(...)
This commit is contained in:
parent
77546b5098
commit
4d4f5e2501
@ -9,14 +9,28 @@
|
|||||||
|
|
||||||
namespace Aurora::IO::Loop
|
namespace Aurora::IO::Loop
|
||||||
{
|
{
|
||||||
|
/// Is the IO primitive is not IPC, entirely inprocess, this might avoid the kernel or a spinloop
|
||||||
|
static const AuUInt8 kFlagLSTryNoSpin = 1;
|
||||||
|
|
||||||
|
/// Disallows IO Async transaction callbacks and APC callbacks from being called
|
||||||
|
static const AuUInt8 kFlagLSTryNoIOAlerts = 2;
|
||||||
|
|
||||||
struct ILoopSource
|
struct ILoopSource
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Atomic is-signaled-and-latch
|
* @brief Atomic is-signaled-and-latch.
|
||||||
|
* Approx equiv to NT: WaitForSingleObjectEx(this, 0, TRUE); but will not break (WAIT_IO_COMPLETION) on APC or IO interruption.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual bool IsSignaled() = 0;
|
virtual bool IsSignaled() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Atomic is-signaled-and-latch.
|
||||||
|
* Approx equiv to NT: WaitForSingleObjectEx(this, 0, !(uFlags & kFlagLSTryNoIOAlerts)); but will not break (WAIT_IO_COMPLETION) on APC or IO interruption
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual bool IsSignaledExt(AuUInt8 uFlags) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a generic description about the loop source handle
|
* @brief Returns a generic description about the loop source handle
|
||||||
* @return
|
* @return
|
||||||
@ -24,9 +38,31 @@ namespace Aurora::IO::Loop
|
|||||||
virtual ELoopSource GetType() = 0;
|
virtual ELoopSource GetType() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @breif Blocks the current thread for the kernel primitives
|
* @breif Blocks the current thread for the kernel primitive.
|
||||||
* @warning Are you looking for LoopQueues? You can even reduce async threads down to kernel ILoopQueue's
|
* @warning Are you looking for LoopQueues? You can even reduce async threads down to kernel ILoopQueues.
|
||||||
|
* @warning see: (stateful wait context) AuIO::Loop::ILoopQueue
|
||||||
|
* @warning see: (arbitrary stateless wait) AuIO::Loop::WaitMultipleLoopSources
|
||||||
|
* @warning see: (arbitrary stateless wait) AuIO::Loop::WaitMultipleLoopSourcesEx
|
||||||
|
* @warning see: (scheduling on registered thread) Async/IThreadPool::ToKernelWorkQueue
|
||||||
|
* @warning see: (scheduling on registered thread) Async/IWorkItem::SetSchedByLoopSourceOnce
|
||||||
|
* @warning see: (scheduling on registered thread) Async/IWorkItem::SetSchedByLoopSourceRepeating
|
||||||
*/
|
*/
|
||||||
virtual bool WaitOn(AuUInt32 timeout = 0) = 0;
|
virtual bool WaitOn(AuUInt32 uTimeoutRelMS = 0) = 0;
|
||||||
|
|
||||||
|
virtual bool WaitOnExt(AuUInt8 uFlags, AuUInt32 uTimeoutRelMS = 0) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Follows steady time & 0 = indefinite convention
|
||||||
|
* @warning: The IO subsystem uses miliseconds internally. Expect under and overshoots.
|
||||||
|
* nanosec resolution is useful for dealing with hidden interruptions requiring a resleep.
|
||||||
|
*/
|
||||||
|
virtual bool WaitOnAbs(AuUInt64 uTimeoutAbs = 0) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Follows steady time & 0 = indefinite convention
|
||||||
|
* @warning: The IO subsystem uses miliseconds internally. Expect under and overshoots.
|
||||||
|
* nanosec resolution is useful for dealing with hidden interruptions requiring a resleep.
|
||||||
|
*/
|
||||||
|
virtual bool WaitOnAbsExt(AuUInt8 uFlags, AuUInt64 uTimeoutAbs = 0) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -19,6 +19,13 @@
|
|||||||
|
|
||||||
namespace Aurora::IO::Loop
|
namespace Aurora::IO::Loop
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// TODO: Win32 enters an alertable state, does not break
|
||||||
|
// Linux does not enter an alertable state, but will soon-ish
|
||||||
|
// There is no flag for enter alertable state
|
||||||
|
// Cannot reach true parity with WaitForMultipleObjectsEx in this current state
|
||||||
|
// Also, there is no flag for awoken by APC
|
||||||
|
|
||||||
// optTimeoutMS = {} | indefinite
|
// optTimeoutMS = {} | indefinite
|
||||||
// optTimeoutMS = 0 | poll
|
// optTimeoutMS = 0 | poll
|
||||||
// optTimeoutMS = 1 | 1ms
|
// optTimeoutMS = 1 | 1ms
|
||||||
|
@ -211,7 +211,8 @@ namespace Aurora
|
|||||||
int io_getevents(aio_context_t ctx,
|
int io_getevents(aio_context_t ctx,
|
||||||
long min_nr, long max_nr,
|
long min_nr, long max_nr,
|
||||||
struct io_event *events,
|
struct io_event *events,
|
||||||
struct timespec *timeout)
|
struct timespec *timeout,
|
||||||
|
bool bStrictUserspaceOnly)
|
||||||
{
|
{
|
||||||
int i {};
|
int i {};
|
||||||
|
|
||||||
@ -256,6 +257,11 @@ namespace Aurora
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bStrictUserspaceOnly)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
do_syscall:
|
do_syscall:
|
||||||
int iKernelCount {};
|
int iKernelCount {};
|
||||||
if ((iKernelCount = syscallFuckYou(__NR_io_getevents,
|
if ((iKernelCount = syscallFuckYou(__NR_io_getevents,
|
||||||
|
@ -56,7 +56,8 @@ namespace Aurora
|
|||||||
|
|
||||||
int io_getevents(aio_context_t ctx, long min_nr, long max_nr,
|
int io_getevents(aio_context_t ctx, long min_nr, long max_nr,
|
||||||
struct io_event *events,
|
struct io_event *events,
|
||||||
struct timespec *timeout);
|
struct timespec *timeout,
|
||||||
|
bool bStrictUserspaceOnly);
|
||||||
|
|
||||||
ssize_t sys_getrandom(void *pBuffer, size_t uLength);
|
ssize_t sys_getrandom(void *pBuffer, size_t uLength);
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ static void LinuxRemoveRobustFutexSlow(AuUInt32 *futex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LinuxLockFutex(AuUInt32 *futex, AuUInt32 timeout)
|
static bool LinuxLockFutex(AuUInt32 *futex, AuUInt32 timeout, AuUInt64 uTimeoutAbs)
|
||||||
{
|
{
|
||||||
bool bContended;
|
bool bContended;
|
||||||
struct timespec tspec;
|
struct timespec tspec;
|
||||||
@ -315,6 +315,10 @@ static bool LinuxLockFutex(AuUInt32 *futex, AuUInt32 timeout)
|
|||||||
{
|
{
|
||||||
AuTime::ms2tsabs(&tspec, timeout);
|
AuTime::ms2tsabs(&tspec, timeout);
|
||||||
}
|
}
|
||||||
|
else if (uTimeoutAbs)
|
||||||
|
{
|
||||||
|
AuTime::ns2ts(&tspec, uTimeoutAbs);
|
||||||
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -322,7 +326,7 @@ static bool LinuxLockFutex(AuUInt32 *futex, AuUInt32 timeout)
|
|||||||
bContended = old != kFutexValueUnlocked;
|
bContended = old != kFutexValueUnlocked;
|
||||||
if (bContended)
|
if (bContended)
|
||||||
{
|
{
|
||||||
int res = Aurora::futex_wait_shared(futex, old, timeout ? &tspec : nullptr);
|
int res = Aurora::futex_wait_shared(futex, old, (timeout || uTimeoutAbs) ? &tspec : nullptr);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
if (res == -ETIMEDOUT)
|
if (res == -ETIMEDOUT)
|
||||||
@ -541,7 +545,7 @@ namespace Aurora::IO::IPC
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!::LinuxLockFutex(futex, timeout))
|
if (!::LinuxLockFutex(futex, timeout, 0))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -581,6 +585,45 @@ namespace Aurora::IO::IPC
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IPCMutexProxy::IsSignaledExt(AuUInt8 uFlags)
|
||||||
|
{
|
||||||
|
return this->IsSignaled();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPCMutexProxy::WaitOnExt(AuUInt8 uFlags, AuUInt32 timeout)
|
||||||
|
{
|
||||||
|
return this->WaitOn(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPCMutexProxy::WaitOnAbs(AuUInt64 uTimeoutAbs)
|
||||||
|
{
|
||||||
|
auto futex = this->GetFutex();
|
||||||
|
if (!futex)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!::LinuxLockFutex(futex, 0, uTimeoutAbs))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->mutex_.IsSignaled())
|
||||||
|
{
|
||||||
|
::LinuxUnlockFutex(futex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->leakSelf_ = AuSharedFromThis();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPCMutexProxy::WaitOnAbsExt(AuUInt8 uFlags, AuUInt64 uTimeoutAbs)
|
||||||
|
{
|
||||||
|
return this->WaitOnAbs(uTimeoutAbs);
|
||||||
|
}
|
||||||
|
|
||||||
Loop::ELoopSource IPCMutexProxy::GetType()
|
Loop::ELoopSource IPCMutexProxy::GetType()
|
||||||
{
|
{
|
||||||
return this->mutex_.GetType();
|
return this->mutex_.GetType();
|
||||||
|
@ -28,6 +28,11 @@ namespace Aurora::IO::IPC
|
|||||||
bool WaitOn(AuUInt32 timeout) override;
|
bool WaitOn(AuUInt32 timeout) override;
|
||||||
Loop::ELoopSource GetType() override;
|
Loop::ELoopSource GetType() override;
|
||||||
|
|
||||||
|
bool IsSignaledExt(AuUInt8 uFlags) override;
|
||||||
|
bool WaitOnExt(AuUInt8 uFlags, AuUInt32 timeout) override;
|
||||||
|
bool WaitOnAbs(AuUInt64 uTimeoutAbs) override;
|
||||||
|
bool WaitOnAbsExt(AuUInt8 uFlags, AuUInt64 uTimeoutAbs) override;
|
||||||
|
|
||||||
AuString ExportToString() override;
|
AuString ExportToString() override;
|
||||||
|
|
||||||
AuUInt32 *GetFutex();
|
AuUInt32 *GetFutex();
|
||||||
|
@ -36,6 +36,7 @@ namespace Aurora::IO::IPC
|
|||||||
~IPCEventProxy();
|
~IPCEventProxy();
|
||||||
|
|
||||||
PROXY_INTERNAL_INTERFACE(event_)
|
PROXY_INTERNAL_INTERFACE(event_)
|
||||||
|
PROXY_LOOPSOURCE_EXT_APIS(event_)
|
||||||
IMPLEMENT_HANDLE
|
IMPLEMENT_HANDLE
|
||||||
|
|
||||||
bool Set() override;
|
bool Set() override;
|
||||||
@ -57,6 +58,7 @@ namespace Aurora::IO::IPC
|
|||||||
~IPCSemaphoreProxy();
|
~IPCSemaphoreProxy();
|
||||||
|
|
||||||
PROXY_INTERNAL_INTERFACE(semaphore_)
|
PROXY_INTERNAL_INTERFACE(semaphore_)
|
||||||
|
PROXY_LOOPSOURCE_EXT_APIS(semaphore_)
|
||||||
IMPLEMENT_HANDLE
|
IMPLEMENT_HANDLE
|
||||||
|
|
||||||
bool AddOne() override;
|
bool AddOne() override;
|
||||||
|
@ -33,6 +33,7 @@ namespace Aurora::IO::IPC
|
|||||||
~IPCMutexProxy();
|
~IPCMutexProxy();
|
||||||
|
|
||||||
PROXY_INTERNAL_INTERFACE(mutex_)
|
PROXY_INTERNAL_INTERFACE(mutex_)
|
||||||
|
PROXY_LOOPSOURCE_EXT_APIS(mutex_)
|
||||||
IMPLEMENT_HANDLE
|
IMPLEMENT_HANDLE
|
||||||
|
|
||||||
bool Unlock() override;
|
bool Unlock() override;
|
||||||
@ -151,6 +152,7 @@ namespace Aurora::IO::IPC
|
|||||||
~IPCEventProxy();
|
~IPCEventProxy();
|
||||||
|
|
||||||
PROXY_INTERNAL_INTERFACE(event_)
|
PROXY_INTERNAL_INTERFACE(event_)
|
||||||
|
PROXY_LOOPSOURCE_EXT_APIS(event_)
|
||||||
IMPLEMENT_HANDLE
|
IMPLEMENT_HANDLE
|
||||||
|
|
||||||
bool Set() override;
|
bool Set() override;
|
||||||
@ -276,6 +278,7 @@ namespace Aurora::IO::IPC
|
|||||||
~IPCSemaphoreProxy();
|
~IPCSemaphoreProxy();
|
||||||
|
|
||||||
PROXY_INTERNAL_INTERFACE(semaphore_)
|
PROXY_INTERNAL_INTERFACE(semaphore_)
|
||||||
|
PROXY_LOOPSOURCE_EXT_APIS(semaphore_)
|
||||||
IMPLEMENT_HANDLE
|
IMPLEMENT_HANDLE
|
||||||
|
|
||||||
bool AddOne() override;
|
bool AddOne() override;
|
||||||
|
@ -82,6 +82,29 @@ namespace Aurora::IO::IPC
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO: 2024/09 (this doesnt belong here but im lazy and no primitive actually needs these overloads)
|
||||||
|
// (fill the entire interface and drop the _IM_SO_LAZY part)
|
||||||
|
|
||||||
|
#define PROXY_LOOPSOURCE_EXT_APIS_(Base) \
|
||||||
|
inline virtual bool IsSignaledExt(AuUInt8 uFlags) override \
|
||||||
|
{ \
|
||||||
|
return Base IsSignaledExt(uFlags); \
|
||||||
|
} \
|
||||||
|
inline virtual bool WaitOnExt(AuUInt8 uFlags, AuUInt32 timeout) override \
|
||||||
|
{ \
|
||||||
|
return Base WaitOnExt(uFlags, timeout); \
|
||||||
|
} \
|
||||||
|
inline virtual bool WaitOnAbs(AuUInt64 uTimeoutAbs) override \
|
||||||
|
{ \
|
||||||
|
return Base WaitOnAbs(uTimeoutAbs); \
|
||||||
|
} \
|
||||||
|
inline virtual bool WaitOnAbsExt(AuUInt8 uFlags, AuUInt64 uTimeoutAbs) override \
|
||||||
|
{ \
|
||||||
|
return Base WaitOnAbsExt(uFlags, uTimeoutAbs); \
|
||||||
|
}
|
||||||
|
|
||||||
#define PROXY_INTERNAL_INTERFACE(Base) PROXY_INTERNAL_INTERFACE_(Base.)
|
#define PROXY_INTERNAL_INTERFACE(Base) PROXY_INTERNAL_INTERFACE_(Base.)
|
||||||
|
#define PROXY_LOOPSOURCE_EXT_APIS(Base) PROXY_LOOPSOURCE_EXT_APIS_(Base.)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -84,7 +84,12 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
bool LSEvent::IsSignaled()
|
bool LSEvent::IsSignaled()
|
||||||
{
|
{
|
||||||
return IsSignaledFromNonblockingImpl(this, this, &LSEvent::IsSignaledNonblocking);
|
return IsSignaledFromNonblockingImpl(this, this, &LSEvent::IsSignaledNonblocking, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LSEvent::IsSignaledExt(AuUInt8 uFlags)
|
||||||
|
{
|
||||||
|
return IsSignaledFromNonblockingImpl(this, this, &LSEvent::IsSignaledNonblocking, !(uFlags & kFlagLSTryNoIOAlerts));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSEvent::WaitOn(AuUInt32 timeout)
|
bool LSEvent::WaitOn(AuUInt32 timeout)
|
||||||
|
@ -17,6 +17,8 @@ namespace Aurora::IO::Loop
|
|||||||
LSEvent(int handle, bool triggered, bool atomicRelease);
|
LSEvent(int handle, bool triggered, bool atomicRelease);
|
||||||
~LSEvent();
|
~LSEvent();
|
||||||
|
|
||||||
|
PROXY_LOOP_LOOPSOURCE_EXT_WAIT_APIS_;
|
||||||
|
|
||||||
bool Set() override;
|
bool Set() override;
|
||||||
bool Reset() override;
|
bool Reset() override;
|
||||||
|
|
||||||
@ -25,6 +27,7 @@ namespace Aurora::IO::Loop
|
|||||||
virtual bool OnTrigger(AuUInt handle) override;
|
virtual bool OnTrigger(AuUInt handle) override;
|
||||||
|
|
||||||
virtual bool IsSignaled() override;
|
virtual bool IsSignaled() override;
|
||||||
|
virtual bool IsSignaledExt(AuUInt8 uFlags) override;
|
||||||
virtual bool WaitOn(AuUInt32 timeout) override;
|
virtual bool WaitOn(AuUInt32 timeout) override;
|
||||||
virtual ELoopSource GetType() override;
|
virtual ELoopSource GetType() override;
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ namespace Aurora::IO::Loop
|
|||||||
LSEvent(bool triggered, bool atomicRelease, bool permitMultipleTriggers);
|
LSEvent(bool triggered, bool atomicRelease, bool permitMultipleTriggers);
|
||||||
~LSEvent();
|
~LSEvent();
|
||||||
|
|
||||||
|
PROXY_LOOP_LOOPSOURCE_EXT_APIS_;
|
||||||
|
|
||||||
bool TryInit(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers);
|
bool TryInit(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers);
|
||||||
|
|
||||||
bool Set() override;
|
bool Set() override;
|
||||||
|
@ -7,15 +7,37 @@
|
|||||||
***/
|
***/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
|
||||||
|
namespace Aurora::IO::UNIX
|
||||||
|
{
|
||||||
|
bool LinuxOverlappedYield(bool bUserspaceOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Aurora::IO::Loop
|
namespace Aurora::IO::Loop
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool IsSignaledFromNonblockingImpl(ILoopSourceEx *source, T * that, bool(T::*IsSignaledNonblocking)())
|
inline bool IsSignaledFromNonblockingImpl(ILoopSourceEx *source, T * that, bool(T::*IsSignaledNonblocking)(), bool bIOTick)
|
||||||
{
|
{
|
||||||
bool val {};
|
bool val {};
|
||||||
source->OnPresleep();
|
source->OnPresleep();
|
||||||
val = ((that)->*(IsSignaledNonblocking))();
|
val = ((that)->*(IsSignaledNonblocking))();
|
||||||
source->OnFinishSleep();
|
source->OnFinishSleep();
|
||||||
|
// Required for precise Windows on Linux OVERLAPPED semantics for emulators.
|
||||||
|
// IAsyncTransaction::Complete()/Wait() will always enter an alertable state and dispatch io completion callbacks.
|
||||||
|
// In theory, we don't need this.
|
||||||
|
// In practice, if NT can atomically set an event and update the apc queue, we could be out of parity.
|
||||||
|
if (bIOTick)
|
||||||
|
{
|
||||||
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
// Do not syscall after read or select again under Linux
|
||||||
|
UNIX::LinuxOverlappedYield(true);
|
||||||
|
#else
|
||||||
|
IOYield();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,6 +9,73 @@
|
|||||||
|
|
||||||
#include "WaitSingle.hpp"
|
#include "WaitSingle.hpp"
|
||||||
|
|
||||||
|
#define PROXY_LOOP_LOOPSOURCE_EXT_WAIT_APIS_ \
|
||||||
|
inline virtual bool WaitOnExt(AuUInt8 uFlags, AuUInt32 timeout) override \
|
||||||
|
{ \
|
||||||
|
return LSHandle::WaitOnExt(uFlags, timeout); \
|
||||||
|
} \
|
||||||
|
inline virtual bool WaitOnAbs(AuUInt64 uTimeoutAbs) override \
|
||||||
|
{ \
|
||||||
|
return LSHandle::WaitOnAbs(uTimeoutAbs); \
|
||||||
|
} \
|
||||||
|
inline virtual bool WaitOnAbsExt(AuUInt8 uFlags, AuUInt64 uTimeoutAbs) override \
|
||||||
|
{ \
|
||||||
|
return LSHandle::WaitOnAbsExt(uFlags, uTimeoutAbs); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PROXY_LOOP_LOOPSOURCE_EXT_APIS_ \
|
||||||
|
inline virtual bool IsSignaledExt(AuUInt8 uFlags) override \
|
||||||
|
{ \
|
||||||
|
return LSHandle::IsSignaledExt(uFlags); \
|
||||||
|
} \
|
||||||
|
PROXY_LOOP_LOOPSOURCE_EXT_WAIT_APIS_
|
||||||
|
|
||||||
|
// TODO: more work required
|
||||||
|
#define PROXY_LOCAL_LOOPSOURCE_EXT_APIS_ \
|
||||||
|
inline virtual bool IsSignaledExt(AuUInt8 uFlags) override \
|
||||||
|
{ \
|
||||||
|
bool bFlagUser = uFlags & kFlagLSTryNoSpin; \
|
||||||
|
if (bFlagUser) \
|
||||||
|
{ \
|
||||||
|
return this->TryTakeNoSpin(); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
return this->TryTakeSpin(); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
inline virtual bool WaitOnExt(AuUInt8 uFlags, AuUInt32 timeout) override \
|
||||||
|
{ \
|
||||||
|
return this->WaitOn(timeout); \
|
||||||
|
} \
|
||||||
|
inline virtual bool WaitOnAbs(AuUInt64 uTimeoutAbs) override \
|
||||||
|
{ \
|
||||||
|
return this->WaitOnAbs(uTimeoutAbs); \
|
||||||
|
} \
|
||||||
|
inline virtual bool WaitOnAbsExt(AuUInt8 uFlags, AuUInt64 uTimeoutAbs) override \
|
||||||
|
{ \
|
||||||
|
if (!uTimeoutAbs) \
|
||||||
|
{ \
|
||||||
|
return this->TryTakeWaitNS(0); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
return this->TryTakeWaitNS(uTimeoutAbs); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
inline virtual bool WaitOn(AuUInt32 timeout) override \
|
||||||
|
{ \
|
||||||
|
if (!timeout) \
|
||||||
|
{ \
|
||||||
|
return this->TryTakeWaitNS(0); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
return this->TryTakeWaitNS(AuMSToNS<AuUInt64>(timeout) + AuTime::SteadyClockNS()); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Aurora::IO::Loop
|
namespace Aurora::IO::Loop
|
||||||
{
|
{
|
||||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
|
@ -84,11 +84,6 @@ namespace Aurora::IO::Loop
|
|||||||
return this->TryTake();
|
return this->TryTake();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSLocalEvent::WaitOn(AuUInt32 timeout)
|
|
||||||
{
|
|
||||||
return this->TryTakeWaitMS(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
ELoopSource LSLocalEvent::GetType()
|
ELoopSource LSLocalEvent::GetType()
|
||||||
{
|
{
|
||||||
return ELoopSource::eSourceFastEvent;
|
return ELoopSource::eSourceFastEvent;
|
||||||
@ -234,12 +229,8 @@ namespace Aurora::IO::Loop
|
|||||||
return this->TryTakeSpin();
|
return this->TryTakeSpin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSLocalEvent::TryTakeWaitMS(AuUInt32 timeout)
|
bool LSLocalEvent::TryTakeWaitNS(AuUInt64 uEndTime)
|
||||||
{
|
{
|
||||||
auto uEndTime = timeout ?
|
|
||||||
AuTime::SteadyClockNS() + AuMSToNS<AuUInt64>(timeout) :
|
|
||||||
0;
|
|
||||||
|
|
||||||
if (this->TryTakeSpin())
|
if (this->TryTakeSpin())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -247,7 +238,7 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
while (!this->TryTakeNoSpin())
|
while (!this->TryTakeNoSpin())
|
||||||
{
|
{
|
||||||
if (!timeout)
|
if (!uEndTime)
|
||||||
{
|
{
|
||||||
if (LSSemaphore::WaitOn(0))
|
if (LSSemaphore::WaitOn(0))
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,6 @@ namespace Aurora::IO::Loop
|
|||||||
bool TryInit(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers);
|
bool TryInit(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers);
|
||||||
|
|
||||||
virtual bool IsSignaled() override;
|
virtual bool IsSignaled() override;
|
||||||
bool WaitOn(AuUInt32 timeout) override;
|
|
||||||
ELoopSource GetType() override;
|
ELoopSource GetType() override;
|
||||||
|
|
||||||
bool Set() override;
|
bool Set() override;
|
||||||
@ -30,7 +29,9 @@ namespace Aurora::IO::Loop
|
|||||||
bool TryTakeNoSpin();
|
bool TryTakeNoSpin();
|
||||||
bool TryTakeSpin();
|
bool TryTakeSpin();
|
||||||
bool TryTake();
|
bool TryTake();
|
||||||
bool TryTakeWaitMS(AuUInt32 timeout);
|
bool TryTakeWaitNS(AuUInt64 timeout);
|
||||||
|
|
||||||
|
PROXY_LOCAL_LOOPSOURCE_EXT_APIS_;
|
||||||
|
|
||||||
bool IsSignaledNoSpinIfUserland() override;
|
bool IsSignaledNoSpinIfUserland() override;
|
||||||
void OnPresleep() override;
|
void OnPresleep() override;
|
||||||
|
@ -91,11 +91,6 @@ namespace Aurora::IO::Loop
|
|||||||
return this->TryTakeNoSpin();
|
return this->TryTakeNoSpin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSLocalMutex::WaitOn(AuUInt32 timeout)
|
|
||||||
{
|
|
||||||
return this->TryTakeWaitMS(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
ELoopSource LSLocalMutex::GetType()
|
ELoopSource LSLocalMutex::GetType()
|
||||||
{
|
{
|
||||||
return ELoopSource::eSourceFastMutex;
|
return ELoopSource::eSourceFastMutex;
|
||||||
@ -119,12 +114,8 @@ namespace Aurora::IO::Loop
|
|||||||
return this->TryTakeSpin();
|
return this->TryTakeSpin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSLocalMutex::TryTakeWaitMS(AuUInt32 timeout)
|
bool LSLocalMutex::TryTakeWaitNS(AuUInt64 uEndTime)
|
||||||
{
|
{
|
||||||
auto uEndTime = timeout ?
|
|
||||||
AuTime::SteadyClockNS() + AuMSToNS<AuUInt64>(timeout) :
|
|
||||||
0;
|
|
||||||
|
|
||||||
if (this->TryTakeSpin())
|
if (this->TryTakeSpin())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -132,7 +123,7 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
while (!this->TryTakeNoSpin())
|
while (!this->TryTakeNoSpin())
|
||||||
{
|
{
|
||||||
if (!timeout)
|
if (!uEndTime)
|
||||||
{
|
{
|
||||||
if (LSSemaphore::WaitOn(0))
|
if (LSSemaphore::WaitOn(0))
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,6 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
bool IsSignaled() override;
|
bool IsSignaled() override;
|
||||||
bool IsSignaledNoSpinIfUserland() override;
|
bool IsSignaledNoSpinIfUserland() override;
|
||||||
bool WaitOn(AuUInt32 timeout) override;
|
|
||||||
ELoopSource GetType() override;
|
ELoopSource GetType() override;
|
||||||
|
|
||||||
bool Unlock() override;
|
bool Unlock() override;
|
||||||
@ -30,7 +29,9 @@ namespace Aurora::IO::Loop
|
|||||||
bool TryTakeNoSpin();
|
bool TryTakeNoSpin();
|
||||||
bool TryTakeSpin();
|
bool TryTakeSpin();
|
||||||
bool TryTake();
|
bool TryTake();
|
||||||
bool TryTakeWaitMS(AuUInt32 timeout);
|
bool TryTakeWaitNS(AuUInt64 timeout);
|
||||||
|
|
||||||
|
PROXY_LOCAL_LOOPSOURCE_EXT_APIS_;
|
||||||
|
|
||||||
AuAUInt32 uAtomicWord {};
|
AuAUInt32 uAtomicWord {};
|
||||||
};
|
};
|
||||||
|
@ -251,11 +251,6 @@ namespace Aurora::IO::Loop
|
|||||||
return this->TryTakeNoSpin();
|
return this->TryTakeNoSpin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSLocalSemaphore::WaitOn(AuUInt32 timeout)
|
|
||||||
{
|
|
||||||
return this->TryTakeWaitMS(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
ELoopSource LSLocalSemaphore::GetType()
|
ELoopSource LSLocalSemaphore::GetType()
|
||||||
{
|
{
|
||||||
return ELoopSource::eSourceFastSemaphore;
|
return ELoopSource::eSourceFastSemaphore;
|
||||||
@ -289,12 +284,8 @@ namespace Aurora::IO::Loop
|
|||||||
return this->TryTakeSpin();
|
return this->TryTakeSpin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSLocalSemaphore::TryTakeWaitMS(AuUInt32 timeout)
|
bool LSLocalSemaphore::TryTakeWaitNS(AuUInt64 uEndTime)
|
||||||
{
|
{
|
||||||
auto uEndTime = timeout ?
|
|
||||||
AuTime::SteadyClockNS() + AuMSToNS<AuUInt64>(timeout) :
|
|
||||||
0;
|
|
||||||
|
|
||||||
if (this->TryTakeSpin())
|
if (this->TryTakeSpin())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -302,7 +293,7 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
while (!this->TryTakeNoSpin())
|
while (!this->TryTakeNoSpin())
|
||||||
{
|
{
|
||||||
if (!timeout)
|
if (!uEndTime)
|
||||||
{
|
{
|
||||||
if (LSSemaphore::WaitOn(0))
|
if (LSSemaphore::WaitOn(0))
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,6 @@ namespace Aurora::IO::Loop
|
|||||||
bool TryInit(AuUInt32 initialCount, AuUInt32 uMaxCount = 0);
|
bool TryInit(AuUInt32 initialCount, AuUInt32 uMaxCount = 0);
|
||||||
|
|
||||||
bool IsSignaled() override;
|
bool IsSignaled() override;
|
||||||
bool WaitOn(AuUInt32 timeout) override;
|
|
||||||
bool IsSignaledNoSpinIfUserland() override;
|
bool IsSignaledNoSpinIfUserland() override;
|
||||||
ELoopSource GetType() override;
|
ELoopSource GetType() override;
|
||||||
|
|
||||||
@ -31,7 +30,9 @@ namespace Aurora::IO::Loop
|
|||||||
bool TryTakeNoSpin();
|
bool TryTakeNoSpin();
|
||||||
bool TryTakeSpin();
|
bool TryTakeSpin();
|
||||||
bool TryTake();
|
bool TryTake();
|
||||||
bool TryTakeWaitMS(AuUInt32 timeout);
|
bool TryTakeWaitNS(AuUInt64 timeout);
|
||||||
|
|
||||||
|
PROXY_LOCAL_LOOPSOURCE_EXT_APIS_;
|
||||||
|
|
||||||
void OnPresleep() override;
|
void OnPresleep() override;
|
||||||
void OnFinishSleep() override;
|
void OnFinishSleep() override;
|
||||||
|
@ -61,7 +61,12 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
bool LSMutex::IsSignaled()
|
bool LSMutex::IsSignaled()
|
||||||
{
|
{
|
||||||
return IsSignaledFromNonblockingImpl(this, this, &LSMutex::IsSignaledNonblocking);
|
return IsSignaledFromNonblockingImpl(this, this, &LSMutex::IsSignaledNonblocking, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LSMutex::IsSignaledExt(AuUInt8 uFlags)
|
||||||
|
{
|
||||||
|
return IsSignaledFromNonblockingImpl(this, this, &LSMutex::IsSignaledNonblocking, !(uFlags & kFlagLSTryNoIOAlerts));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSMutex::WaitOn(AuUInt32 timeout)
|
bool LSMutex::WaitOn(AuUInt32 timeout)
|
||||||
|
@ -16,11 +16,14 @@ namespace Aurora::IO::Loop
|
|||||||
LSMutex(int handle);
|
LSMutex(int handle);
|
||||||
~LSMutex();
|
~LSMutex();
|
||||||
|
|
||||||
|
PROXY_LOOP_LOOPSOURCE_EXT_WAIT_APIS_;
|
||||||
|
|
||||||
bool Unlock() override;
|
bool Unlock() override;
|
||||||
|
|
||||||
virtual bool OnTrigger(AuUInt handle) override;
|
virtual bool OnTrigger(AuUInt handle) override;
|
||||||
|
|
||||||
bool IsSignaled() override;
|
bool IsSignaled() override;
|
||||||
|
bool IsSignaledExt(AuUInt8 uFlags) override;
|
||||||
bool WaitOn(AuUInt32 timeout) override;
|
bool WaitOn(AuUInt32 timeout) override;
|
||||||
virtual ELoopSource GetType() override;
|
virtual ELoopSource GetType() override;
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@ namespace Aurora::IO::Loop
|
|||||||
LSMutex(HANDLE handle);
|
LSMutex(HANDLE handle);
|
||||||
~LSMutex();
|
~LSMutex();
|
||||||
|
|
||||||
|
PROXY_LOOP_LOOPSOURCE_EXT_APIS_;
|
||||||
|
|
||||||
bool Unlock() override;
|
bool Unlock() override;
|
||||||
|
|
||||||
bool IsSignaled() override;
|
bool IsSignaled() override;
|
||||||
|
@ -85,7 +85,12 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
bool LSSemaphore::IsSignaled()
|
bool LSSemaphore::IsSignaled()
|
||||||
{
|
{
|
||||||
return IsSignaledFromNonblockingImpl(this, this, &LSSemaphore::IsSignaledNonblocking);
|
return IsSignaledFromNonblockingImpl(this, this, &LSSemaphore::IsSignaledNonblocking, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LSSemaphore::IsSignaledExt(AuUInt8 uFlags)
|
||||||
|
{
|
||||||
|
return IsSignaledFromNonblockingImpl(this, this, &LSSemaphore::IsSignaledNonblocking, !(uFlags & kFlagLSTryNoIOAlerts));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSSemaphore::WaitOn(AuUInt32 timeout)
|
bool LSSemaphore::WaitOn(AuUInt32 timeout)
|
||||||
|
@ -17,15 +17,17 @@ namespace Aurora::IO::Loop
|
|||||||
LSSemaphore(int handle, int tag);
|
LSSemaphore(int handle, int tag);
|
||||||
~LSSemaphore();
|
~LSSemaphore();
|
||||||
|
|
||||||
|
PROXY_LOOP_LOOPSOURCE_EXT_WAIT_APIS_;
|
||||||
|
|
||||||
bool TryInit(AuUInt32 initialCount = 0);
|
bool TryInit(AuUInt32 initialCount = 0);
|
||||||
|
|
||||||
bool AddOne() override;
|
bool AddOne() override;
|
||||||
bool AddMany(AuUInt32 uCount) override;
|
bool AddMany(AuUInt32 uCount) override;
|
||||||
|
|
||||||
|
|
||||||
virtual bool OnTrigger(AuUInt handle) override;
|
virtual bool OnTrigger(AuUInt handle) override;
|
||||||
|
|
||||||
bool IsSignaled() override;
|
bool IsSignaled() override;
|
||||||
|
bool IsSignaledExt(AuUInt8 uFlags) override;
|
||||||
bool WaitOn(AuUInt32 timeout) override;
|
bool WaitOn(AuUInt32 timeout) override;
|
||||||
virtual ELoopSource GetType() override;
|
virtual ELoopSource GetType() override;
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ namespace Aurora::IO::Loop
|
|||||||
LSSemaphore(HANDLE handle);
|
LSSemaphore(HANDLE handle);
|
||||||
~LSSemaphore();
|
~LSSemaphore();
|
||||||
|
|
||||||
|
PROXY_LOOP_LOOPSOURCE_EXT_APIS_;
|
||||||
|
|
||||||
bool TryInit(AuUInt32 initialCount = 0);
|
bool TryInit(AuUInt32 initialCount = 0);
|
||||||
|
|
||||||
bool AddOne() override;
|
bool AddOne() override;
|
||||||
|
@ -56,7 +56,7 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
bool LSSignalCatcher::IsSignaled()
|
bool LSSignalCatcher::IsSignaled()
|
||||||
{
|
{
|
||||||
return IsSignaledFromNonblockingImpl(this, this, &LSSignalCatcher::IsSignaledNonblocking);
|
return IsSignaledFromNonblockingImpl(this, this, &LSSignalCatcher::IsSignaledNonblocking, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSSignalCatcher::WaitOn(AuUInt32 timeout)
|
bool LSSignalCatcher::WaitOn(AuUInt32 timeout)
|
||||||
|
@ -82,7 +82,12 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
bool LSTimer::IsSignaled()
|
bool LSTimer::IsSignaled()
|
||||||
{
|
{
|
||||||
return IsSignaledFromNonblockingImpl(this, this, &LSTimer::IsSignaledNonblocking);
|
return IsSignaledFromNonblockingImpl(this, this, &LSTimer::IsSignaledNonblocking, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LSTimer::IsSignaledExt(AuUInt8 uFlags)
|
||||||
|
{
|
||||||
|
return IsSignaledFromNonblockingImpl(this, this, &LSTimer::IsSignaledNonblocking, !(uFlags & kFlagLSTryNoIOAlerts));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSTimer::WaitOn(AuUInt32 timeout)
|
bool LSTimer::WaitOn(AuUInt32 timeout)
|
||||||
|
@ -15,6 +15,8 @@ namespace Aurora::IO::Loop
|
|||||||
LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, int handle);
|
LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, int handle);
|
||||||
~LSTimer();
|
~LSTimer();
|
||||||
|
|
||||||
|
PROXY_LOOP_LOOPSOURCE_EXT_WAIT_APIS_;
|
||||||
|
|
||||||
virtual void UpdateTime(AuUInt64 absTimeMs) override;
|
virtual void UpdateTime(AuUInt64 absTimeMs) override;
|
||||||
virtual void UpdateTimeNs(AuUInt64 absTimeNs) override;
|
virtual void UpdateTimeNs(AuUInt64 absTimeNs) override;
|
||||||
virtual void UpdateTickRateIfAny(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero) override;
|
virtual void UpdateTickRateIfAny(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero) override;
|
||||||
@ -24,6 +26,7 @@ namespace Aurora::IO::Loop
|
|||||||
virtual bool OnTrigger(AuUInt handle) override;
|
virtual bool OnTrigger(AuUInt handle) override;
|
||||||
|
|
||||||
virtual bool IsSignaled() override;
|
virtual bool IsSignaled() override;
|
||||||
|
virtual bool IsSignaledExt(AuUInt8 uFlags) override;
|
||||||
virtual bool WaitOn(AuUInt32 timeout) override;
|
virtual bool WaitOn(AuUInt32 timeout) override;
|
||||||
virtual ELoopSource GetType() override;
|
virtual ELoopSource GetType() override;
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@ namespace Aurora::IO::Loop
|
|||||||
LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, HANDLE handle);
|
LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, HANDLE handle);
|
||||||
~LSTimer();
|
~LSTimer();
|
||||||
|
|
||||||
|
PROXY_LOOP_LOOPSOURCE_EXT_APIS_;
|
||||||
|
|
||||||
virtual void UpdateTime(AuUInt64 absTimeMs) override;
|
virtual void UpdateTime(AuUInt64 absTimeMs) override;
|
||||||
virtual void UpdateTimeNs(AuUInt64 absTimeNs) override;
|
virtual void UpdateTimeNs(AuUInt64 absTimeNs) override;
|
||||||
virtual void UpdateTickRateIfAny(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero) override;
|
virtual void UpdateTickRateIfAny(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero) override;
|
||||||
|
@ -10,6 +10,16 @@
|
|||||||
#include "ILoopSourceEx.hpp"
|
#include "ILoopSourceEx.hpp"
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
|
||||||
|
namespace Aurora::IO::UNIX
|
||||||
|
{
|
||||||
|
bool LinuxOverlappedYield(bool bUserspaceOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Aurora::IO::Loop
|
namespace Aurora::IO::Loop
|
||||||
{
|
{
|
||||||
AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjects(const AuList<AuSPtr<ILoopSource>> &objects, bool bZeroTick, AuUInt32 dwTimeoutReq, bool bAllowOthers, bool &bTooMany)
|
AuList<AuSPtr<ILoopSource>> WaitMultipleOrObjects(const AuList<AuSPtr<ILoopSource>> &objects, bool bZeroTick, AuUInt32 dwTimeoutReq, bool bAllowOthers, bool &bTooMany)
|
||||||
@ -194,6 +204,16 @@ namespace Aurora::IO::Loop
|
|||||||
source->OnFinishSleep();
|
source->OnFinishSleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: ugly workaround (see: LSFromHdNonblocking rationale) for an ugly TODO issue implicating all targets (see public Loop.hpp)
|
||||||
|
{
|
||||||
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
// Do not syscall after read or select again under Linux
|
||||||
|
UNIX::LinuxOverlappedYield(true);
|
||||||
|
#else
|
||||||
|
IOYield();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return triggered;
|
return triggered;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace Aurora::IO::Loop
|
namespace Aurora::IO::Loop
|
||||||
{
|
{
|
||||||
bool WaitSingleGeneric::WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles, AuUInt &one)
|
bool WaitSingleGeneric::WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles, AuUInt &one, bool bNoAlert)
|
||||||
{
|
{
|
||||||
if (handles.empty())
|
if (handles.empty())
|
||||||
{
|
{
|
||||||
@ -43,7 +43,7 @@ namespace Aurora::IO::Loop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = WaitForSingleObjectEx(reinterpret_cast<HANDLE>(handles.at(0)), uRemMS, true);
|
ret = WaitForSingleObjectEx(reinterpret_cast<HANDLE>(handles.at(0)), uRemMS, bNoAlert ? FALSE : TRUE);
|
||||||
|
|
||||||
if (timeout &&
|
if (timeout &&
|
||||||
ret != WAIT_IO_COMPLETION &&
|
ret != WAIT_IO_COMPLETION &&
|
||||||
@ -94,7 +94,7 @@ namespace Aurora::IO::Loop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = WaitForMultipleObjectsEx(ntHandles.size(), ntHandles.data(), false, uRemMS, true);
|
ret = WaitForMultipleObjectsEx(ntHandles.size(), ntHandles.data(), false, uRemMS, bNoAlert ? FALSE : TRUE);
|
||||||
if (ret < WAIT_OBJECT_0)
|
if (ret < WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -121,13 +121,13 @@ namespace Aurora::IO::Loop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaitSingleGeneric::WaitForOne(AuUInt32 timeout, AuUInt handle)
|
bool WaitSingleGeneric::WaitForOne(AuUInt32 timeout, AuUInt handle, bool bNoAlert)
|
||||||
{
|
{
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = WaitForSingleObjectEx(reinterpret_cast<HANDLE>(handle), timeout, true);
|
ret = WaitForSingleObjectEx(reinterpret_cast<HANDLE>(handle), timeout, bNoAlert ? FALSE : TRUE);
|
||||||
}
|
}
|
||||||
while (ret == WAIT_IO_COMPLETION);
|
while (ret == WAIT_IO_COMPLETION);
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ namespace Aurora::IO::Loop
|
|||||||
{
|
{
|
||||||
struct WaitSingleGeneric : virtual WaitSingleBase
|
struct WaitSingleGeneric : virtual WaitSingleBase
|
||||||
{
|
{
|
||||||
virtual bool WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles, AuUInt &one) override;
|
virtual bool WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles, AuUInt &one, bool bNoAlert) override;
|
||||||
virtual bool WaitForOne(AuUInt32 timeout, AuUInt handle) override;
|
virtual bool WaitForOne(AuUInt32 timeout, AuUInt handle, bool bNoAlert) override;
|
||||||
virtual void OnPresleep() override;
|
virtual void OnPresleep() override;
|
||||||
virtual void OnFinishSleep() override;
|
virtual void OnFinishSleep() override;
|
||||||
virtual ELoopSource GetType() override;
|
virtual ELoopSource GetType() override;
|
||||||
|
@ -15,13 +15,17 @@
|
|||||||
|
|
||||||
namespace Aurora::IO::Loop
|
namespace Aurora::IO::Loop
|
||||||
{
|
{
|
||||||
bool WaitSingleGeneric::WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles, const AuList<AuUInt> &handlesWrite, AuUInt &one, AuUInt &two)
|
bool WaitSingleGeneric::WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles, const AuList<AuUInt> &handlesWrite, AuUInt &one, AuUInt &two, bool bNoAlert)
|
||||||
{
|
{
|
||||||
fd_set readSet, writeSet;
|
fd_set readSet, writeSet;
|
||||||
AuUInt maxHandle {};
|
AuUInt maxHandle {};
|
||||||
struct timeval tv {};
|
struct timeval tv {};
|
||||||
|
int active;
|
||||||
|
|
||||||
|
if (!bNoAlert)
|
||||||
|
{
|
||||||
// TODO: IO SUBMIT HOOK
|
// TODO: IO SUBMIT HOOK
|
||||||
|
}
|
||||||
|
|
||||||
FD_ZERO(&readSet);
|
FD_ZERO(&readSet);
|
||||||
FD_ZERO(&writeSet);
|
FD_ZERO(&writeSet);
|
||||||
@ -45,12 +49,19 @@ namespace Aurora::IO::Loop
|
|||||||
maxHandle = AuMax(maxHandle, i + 1);
|
maxHandle = AuMax(maxHandle, i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto active = select(maxHandle,
|
active = select(maxHandle,
|
||||||
handles.size() ? &readSet : nullptr,
|
handles.size() ? &readSet : nullptr,
|
||||||
handlesWrite.size() ? &writeSet : nullptr,
|
handlesWrite.size() ? &writeSet : nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
timeout == AuUInt32(-1) ? nullptr : &tv);
|
timeout == AuUInt32(-1) ? nullptr : &tv);
|
||||||
|
|
||||||
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
if (!bNoAlert)
|
||||||
|
{
|
||||||
|
(void)IO::UNIX::LinuxOverlappedYield();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (active == -1)
|
if (active == -1)
|
||||||
{
|
{
|
||||||
// todo push error
|
// todo push error
|
||||||
@ -87,17 +98,25 @@ namespace Aurora::IO::Loop
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaitSingleGeneric::WaitForOne(AuUInt32 timeout, AuUInt read, AuUInt write)
|
// TODO: pass u64 end time, use pselect when available, fallback to this old logic
|
||||||
|
// LinuxOverlappedWaitForOne doesnt understand yields, we have a specific yield op like the thread waitables, but that doesnt help with a single fd
|
||||||
|
// pselect doesnt help much considering we need monotonic clock sleeps
|
||||||
|
// also when we get around to freebsd support, we need to append one to the select array to handle a kqueue of thread local APCs + transactions
|
||||||
|
// this is a mess and will continue to be a mess
|
||||||
|
bool WaitSingleGeneric::WaitForOne(AuUInt32 timeout, AuUInt read, AuUInt write, bool bNoAlert)
|
||||||
{
|
{
|
||||||
fd_set readSet, writeSet;
|
fd_set readSet, writeSet;
|
||||||
struct timeval tv {};
|
struct timeval tv {};
|
||||||
int maxFd {};
|
int maxFd {};
|
||||||
|
int active;
|
||||||
|
|
||||||
|
// TODO: see todo
|
||||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
if (!bNoAlert &&
|
||||||
|
timeout)
|
||||||
{
|
{
|
||||||
bool bWriteTriggered, bReadTriggered;
|
bool bWriteTriggered, bReadTriggered;
|
||||||
|
if (IO::UNIX::LinuxOverlappedWaitForOne(timeout == AuUInt32(-1) ? 0 : timeout, read, write, bReadTriggered, bWriteTriggered))
|
||||||
if (IO::UNIX::LinuxOverlappedWaitForOne(timeout, read, write, bReadTriggered, bWriteTriggered))
|
|
||||||
{
|
{
|
||||||
if (!bWriteTriggered && !bReadTriggered)
|
if (!bWriteTriggered && !bReadTriggered)
|
||||||
{
|
{
|
||||||
@ -129,12 +148,21 @@ namespace Aurora::IO::Loop
|
|||||||
maxFd = AuMax(maxFd, int(write) + 1);
|
maxFd = AuMax(maxFd, int(write) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto active = select(maxFd,
|
active = select(maxFd,
|
||||||
read != -1 ? &readSet : nullptr,
|
read != -1 ? &readSet : nullptr,
|
||||||
write != -1 ? &writeSet : nullptr,
|
write != -1 ? &writeSet : nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
timeout == AuUInt32(-1) ? nullptr : &tv);
|
timeout == AuUInt32(-1) ? nullptr : &tv);
|
||||||
|
|
||||||
|
// TODO: see todo
|
||||||
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
if (!bNoAlert &&
|
||||||
|
!timeout)
|
||||||
|
{
|
||||||
|
(void)IO::UNIX::LinuxOverlappedYield();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (active == 0)
|
if (active == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -11,8 +11,8 @@ namespace Aurora::IO::Loop
|
|||||||
{
|
{
|
||||||
struct WaitSingleGeneric : virtual WaitSingleBase
|
struct WaitSingleGeneric : virtual WaitSingleBase
|
||||||
{
|
{
|
||||||
virtual bool WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles _OPT_WRITE_ARRAY, AuUInt &read _OPT_WRITE_REF) override;
|
virtual bool WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles _OPT_WRITE_ARRAY, AuUInt &read _OPT_WRITE_REF, bool bNoAlert) override;
|
||||||
virtual bool WaitForOne(AuUInt32 timeout, AuUInt handle _OPT_WRITE) override;
|
virtual bool WaitForOne(AuUInt32 timeout, AuUInt handle _OPT_WRITE, bool bNoAlert) override;
|
||||||
virtual void OnPresleep() override;
|
virtual void OnPresleep() override;
|
||||||
virtual void OnFinishSleep() override;
|
virtual void OnFinishSleep() override;
|
||||||
virtual ELoopSource GetType() override;
|
virtual ELoopSource GetType() override;
|
||||||
|
@ -16,10 +16,24 @@ namespace Aurora::IO::Loop
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool WaitSingleBase::IsSignaled()
|
bool WaitSingleBase::IsSignaled()
|
||||||
|
{
|
||||||
|
return this->IsSignaledExt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitSingleBase::IsSignaledExt(AuUInt8 uFlags)
|
||||||
{
|
{
|
||||||
bool val {};
|
bool val {};
|
||||||
AuUInt one {AuNumericLimits<AuUInt>::max()};
|
AuUInt one {AuNumericLimits<AuUInt>::max()};
|
||||||
AuUInt two {AuNumericLimits<AuUInt>::max()};
|
AuUInt two {AuNumericLimits<AuUInt>::max()};
|
||||||
|
|
||||||
|
bool bFlagUser = uFlags & kFlagLSTryNoSpin;
|
||||||
|
bool bFlagNoAlert = uFlags & kFlagLSTryNoIOAlerts;
|
||||||
|
|
||||||
|
if (bFlagUser)
|
||||||
|
{
|
||||||
|
return this->IsSignaledNoSpinIfUserland();
|
||||||
|
}
|
||||||
|
|
||||||
this->OnPresleep();
|
this->OnPresleep();
|
||||||
|
|
||||||
if (this->Singular())
|
if (this->Singular())
|
||||||
@ -27,10 +41,10 @@ namespace Aurora::IO::Loop
|
|||||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
auto handle = this->GetHandle();
|
auto handle = this->GetHandle();
|
||||||
auto handleRw = this->GetWriteHandle();
|
auto handleRw = this->GetWriteHandle();
|
||||||
val = this->WaitForOne(0, handle, handleRw);
|
val = this->WaitForOne(0, handle, handleRw, bFlagNoAlert);
|
||||||
#else
|
#else
|
||||||
auto handle = this->GetHandle();
|
auto handle = this->GetHandle();
|
||||||
val = this->WaitForOne(0, handle);
|
val = this->WaitForOne(0, handle, bFlagNoAlert);
|
||||||
#endif
|
#endif
|
||||||
if (val)
|
if (val)
|
||||||
{
|
{
|
||||||
@ -42,11 +56,11 @@ namespace Aurora::IO::Loop
|
|||||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
auto handles = this->GetHandles();
|
auto handles = this->GetHandles();
|
||||||
auto handlesRw = this->GetWriteHandles();
|
auto handlesRw = this->GetWriteHandles();
|
||||||
val = this->WaitForAtleastOne(0, handles, handlesRw, one, two);
|
val = this->WaitForAtleastOne(0, handles, handlesRw, one, two, bFlagNoAlert);
|
||||||
if (one == -1) one = two;
|
if (one == -1) one = two;
|
||||||
#else
|
#else
|
||||||
auto handles = this->GetHandles();
|
auto handles = this->GetHandles();
|
||||||
val = this->WaitForAtleastOne(0, handles, one);
|
val = this->WaitForAtleastOne(0, handles, one, bFlagNoAlert);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (val)
|
if (val)
|
||||||
@ -61,27 +75,93 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
bool WaitSingleBase::WaitOn(AuUInt32 timeout)
|
bool WaitSingleBase::WaitOn(AuUInt32 timeout)
|
||||||
{
|
{
|
||||||
bool val {};
|
return this->WaitOnExt(0, timeout);
|
||||||
AuUInt one {AuNumericLimits<AuUInt>::max()};
|
}
|
||||||
AuUInt two {AuNumericLimits<AuUInt>::max()};
|
|
||||||
|
|
||||||
this->OnPresleep();
|
bool WaitSingleBase::WaitOnExt(AuUInt8 uFlags, AuUInt32 timeout)
|
||||||
|
{
|
||||||
|
bool bFlagUser = uFlags & kFlagLSTryNoSpin;
|
||||||
|
|
||||||
|
if (bFlagUser)
|
||||||
|
{
|
||||||
|
if (this->IsSignaledNoSpinIfUserland())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uFlags &= ~kFlagLSTryNoSpin;
|
||||||
|
}
|
||||||
|
|
||||||
auto uEndTime = timeout ?
|
auto uEndTime = timeout ?
|
||||||
AuTime::SteadyClockNS() + AuMSToNS<AuUInt64>(timeout) :
|
AuTime::SteadyClockNS() + AuMSToNS<AuUInt64>(timeout) :
|
||||||
0;
|
0;
|
||||||
|
|
||||||
|
return this->WaitOnAbsExt(uFlags, uEndTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitSingleBase::WaitOnAbs(AuUInt64 uTimeoutAbs)
|
||||||
|
{
|
||||||
|
return this->WaitOnAbsExt(0, uTimeoutAbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitSingleBase::WaitOnAbsExt(AuUInt8 uFlags, AuUInt64 uEndTime)
|
||||||
|
{
|
||||||
|
bool val {};
|
||||||
|
AuUInt32 uMSTimeout {};
|
||||||
|
AuUInt64 uNSTimeout {};
|
||||||
|
bool bAgain {};
|
||||||
|
AuUInt one {AuNumericLimits<AuUInt>::max()};
|
||||||
|
AuUInt two {AuNumericLimits<AuUInt>::max()};
|
||||||
|
|
||||||
|
bool bFlagUser = uFlags & kFlagLSTryNoSpin;
|
||||||
|
bool bFlagNoAlert = uFlags & kFlagLSTryNoIOAlerts;
|
||||||
|
|
||||||
|
if (bFlagUser)
|
||||||
|
{
|
||||||
|
if (this->IsSignaledNoSpinIfUserland())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->OnPresleep();
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
if (uEndTime)
|
||||||
|
{
|
||||||
|
auto uStartTime = Time::SteadyClockNS();
|
||||||
|
if (uStartTime >= uEndTime)
|
||||||
|
{
|
||||||
|
uMSTimeout = 0;
|
||||||
|
uNSTimeout = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uNSTimeout = uEndTime - uStartTime;
|
||||||
|
uMSTimeout = AuNSToMS<AuInt64>(uNSTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bAgain && !uMSTimeout)
|
||||||
|
{
|
||||||
|
val = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uMSTimeout = AuUInt32(-1);
|
||||||
|
}
|
||||||
|
|
||||||
if (this->Singular())
|
if (this->Singular())
|
||||||
{
|
{
|
||||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
auto handle = this->GetHandle();
|
auto handle = this->GetHandle();
|
||||||
auto handleRw = this->GetWriteHandle();
|
auto handleRw = this->GetWriteHandle();
|
||||||
val = this->WaitForOne(timeout ? timeout : AuUInt32(-1), handle, handleRw);
|
val = this->WaitForOne(uMSTimeout, handle, handleRw, bFlagNoAlert);
|
||||||
#else
|
#else
|
||||||
auto handle = this->GetHandle();
|
auto handle = this->GetHandle();
|
||||||
val = this->WaitForOne(timeout ? timeout : AuUInt32(-1), handle);
|
val = this->WaitForOne(uMSTimeout, handle, bFlagNoAlert);
|
||||||
#endif
|
#endif
|
||||||
if (val)
|
if (val)
|
||||||
{
|
{
|
||||||
@ -93,11 +173,11 @@ namespace Aurora::IO::Loop
|
|||||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
auto handles = this->GetHandles();
|
auto handles = this->GetHandles();
|
||||||
auto handlesRw = this->GetWriteHandles();
|
auto handlesRw = this->GetWriteHandles();
|
||||||
val = this->WaitForAtleastOne(timeout ? timeout : AuUInt32(-1), handles, handlesRw, one, two);
|
val = this->WaitForAtleastOne(uMSTimeout, handles, handlesRw, one, two, bFlagNoAlert);
|
||||||
if (one == -1) one = two;
|
if (one == -1) one = two;
|
||||||
#else
|
#else
|
||||||
auto handles = this->GetHandles();
|
auto handles = this->GetHandles();
|
||||||
val = this->WaitForAtleastOne(timeout ? timeout : AuUInt32(-1), handles, one);
|
val = this->WaitForAtleastOne(uMSTimeout, handles, one, bFlagNoAlert);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (val)
|
if (val)
|
||||||
@ -106,18 +186,9 @@ namespace Aurora::IO::Loop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout)
|
bAgain = true;
|
||||||
{
|
|
||||||
auto uStartTime = Time::SteadyClockNS();
|
|
||||||
if (uStartTime >= uEndTime)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
while (uEndTime && !val);
|
||||||
timeout = AuNSToMS<AuInt64>(uEndTime - uStartTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (timeout && !val);
|
|
||||||
|
|
||||||
this->OnFinishSleep();
|
this->OnFinishSleep();
|
||||||
return val;
|
return val;
|
||||||
|
@ -29,11 +29,14 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
struct WaitSingleBase : virtual ILoopSourceEx
|
struct WaitSingleBase : virtual ILoopSourceEx
|
||||||
{
|
{
|
||||||
|
virtual bool IsSignaledExt(AuUInt8 uFlags) override;
|
||||||
virtual bool IsSignaledNoSpinIfUserland() override;
|
virtual bool IsSignaledNoSpinIfUserland() override;
|
||||||
virtual bool IsSignaled() override;
|
virtual bool IsSignaled() override;
|
||||||
|
virtual bool WaitOnExt(AuUInt8 uFlags, AuUInt32 timeout) override;
|
||||||
virtual bool WaitOn(AuUInt32 timeout) override;
|
virtual bool WaitOn(AuUInt32 timeout) override;
|
||||||
|
virtual bool WaitOnAbs(AuUInt64 uTimeoutAbs) override;
|
||||||
virtual bool WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles _OPT_WRITE_ARRAY, AuUInt &one _OPT_WRITE_REF) = 0;
|
virtual bool WaitOnAbsExt(AuUInt8 uFlags, AuUInt64 uTimeoutAbs) override;
|
||||||
virtual bool WaitForOne(AuUInt32 timeout, AuUInt handle _OPT_WRITE) = 0;
|
virtual bool WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles _OPT_WRITE_ARRAY, AuUInt &one _OPT_WRITE_REF, bool bNoAlert) = 0;
|
||||||
|
virtual bool WaitForOne(AuUInt32 timeout, AuUInt handle _OPT_WRITE, bool bNoAlert) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -580,7 +580,7 @@ namespace Aurora::IO::UNIX
|
|||||||
AuTime::ns2ts(&targetTime, uTimeNow - uTargetTime);
|
AuTime::ns2ts(&targetTime, uTimeNow - uTargetTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr);
|
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr, false);
|
||||||
|
|
||||||
if (temp >= 0)
|
if (temp >= 0)
|
||||||
{
|
{
|
||||||
@ -748,7 +748,7 @@ namespace Aurora::IO::UNIX
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
temp = io_getevents(io->context, 1, uCount, ioEvents, timeout ? &targetTime : nullptr);
|
temp = io_getevents(io->context, 1, uCount, ioEvents, timeout ? &targetTime : nullptr, false);
|
||||||
|
|
||||||
if (temp >= 0)
|
if (temp >= 0)
|
||||||
{
|
{
|
||||||
@ -971,7 +971,7 @@ namespace Aurora::IO::UNIX
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
temp = io_getevents(io->context, 1, uCount, ioEvents, timeout ? &targetTime : nullptr);
|
temp = io_getevents(io->context, 1, uCount, ioEvents, timeout ? &targetTime : nullptr, false);
|
||||||
|
|
||||||
if (temp >= 0)
|
if (temp >= 0)
|
||||||
{
|
{
|
||||||
@ -1106,7 +1106,7 @@ namespace Aurora::IO::UNIX
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LinuxOverlappedYield()
|
bool LinuxOverlappedYield(bool bUserspaceOnly)
|
||||||
{
|
{
|
||||||
io_event ioEvents[512];
|
io_event ioEvents[512];
|
||||||
int temp;
|
int temp;
|
||||||
@ -1131,7 +1131,7 @@ namespace Aurora::IO::UNIX
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp = io_getevents(io->context, 1, 512, ioEvents, &targetTime);
|
temp = io_getevents(io->context, 1, 512, ioEvents, &targetTime, bUserspaceOnly);
|
||||||
|
|
||||||
if (temp >= 0)
|
if (temp >= 0)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/aio_abi.h>
|
#include <linux/aio_abi.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
namespace Aurora::IO::UNIX
|
namespace Aurora::IO::UNIX
|
||||||
{
|
{
|
||||||
@ -64,8 +65,10 @@ namespace Aurora::IO::UNIX
|
|||||||
|
|
||||||
int LinuxOverlappedEpollShim(int epfd, struct epoll_event *events,
|
int LinuxOverlappedEpollShim(int epfd, struct epoll_event *events,
|
||||||
int maxevents, int timeout);
|
int maxevents, int timeout);
|
||||||
|
// TODO:
|
||||||
|
//int LinuxOverlappedPosixPoll(struct pollfd *pPollFDs, nfds_t uCount, int timeout);
|
||||||
|
|
||||||
bool LinuxOverlappedYield();
|
bool LinuxOverlappedYield(bool bUserspaceOnly = false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user