From 70418df761c82767654d59eeb00930db6cde3f7c Mon Sep 17 00:00:00 2001 From: Reece Wilson Date: Tue, 28 Jun 2022 15:57:29 +0100 Subject: [PATCH] [+] Added extended IO apis > StartSimpleLSWatchEx > StartSimpleIOWatchEx > StartIOWatchEx [*] Update README --- Include/Aurora/IO/IIOProcessor.hpp | 27 +++++---- Include/Aurora/IO/IIOWaitableIOLoopSource.hpp | 1 + Include/Aurora/IO/IIOWaitableItem.hpp | 1 + README.md | 13 ++++ Source/IO/IOPipeProcessor.cpp | 1 + Source/IO/IOProcessor.cpp | 60 +++++++++++++++---- Source/IO/IOProcessor.hpp | 5 ++ Source/IO/IOProcessorItem.cpp | 24 +++++++- Source/IO/IOProcessorItem.hpp | 9 ++- Source/IO/IOWaitableIOLoopSource.cpp | 17 +++++- Source/IO/IOWaitableIOLoopSource.hpp | 5 +- Source/IO/IOWaitableIOTimer.cpp | 5 ++ Source/IO/IOWaitableIOTimer.hpp | 2 + 13 files changed, 141 insertions(+), 29 deletions(-) diff --git a/Include/Aurora/IO/IIOProcessor.hpp b/Include/Aurora/IO/IIOProcessor.hpp index bb4fc9a8..b9a2c947 100644 --- a/Include/Aurora/IO/IIOProcessor.hpp +++ b/Include/Aurora/IO/IIOProcessor.hpp @@ -11,22 +11,27 @@ namespace Aurora::IO { struct IIOProcessor { - virtual AuUInt32 TryTick () = 0; - virtual AuUInt32 RunTick () = 0; - virtual AuUInt32 TickFor (const AuSPtr &ioEvent) = 0; + virtual AuUInt32 TryTick () = 0; + virtual AuUInt32 RunTick () = 0; + virtual AuUInt32 TickFor (const AuSPtr &ioEvent) = 0; - virtual AuUInt32 ManualTick () = 0; + virtual AuUInt32 ManualTick () = 0; - virtual AuUInt64 SetRefreshRate (AuUInt64 ns) = 0; - virtual bool HasRefreshRate () = 0; + virtual AuUInt64 SetRefreshRate (AuUInt64 ns) = 0; + virtual bool HasRefreshRate () = 0; virtual bool MultiplexRefreshRateWithIOEvents() = 0; - virtual AuUInt64 GetOwnedThreadId () = 0; - - virtual AuSPtr StartIOWatch (const AuSPtr &object, const AuSPtr &listener) = 0; - virtual AuSPtr StartSimpleIOWatch (const AuSPtr &object, const AuSPtr &listener) = 0; - virtual AuSPtr StartSimpleLSWatch (const AuSPtr &source, const AuSPtr &listener) = 0; + virtual AuUInt64 GetOwnedThreadId () = 0; + + virtual AuSPtr StartIOWatch (const AuSPtr &object, const AuSPtr &listener) = 0; + virtual AuSPtr StartIOWatchEx (const AuSPtr &object, const AuSPtr &listener, bool singleshot) = 0; + + virtual AuSPtr StartSimpleIOWatch (const AuSPtr &object, const AuSPtr &listener) = 0; + virtual AuSPtr StartSimpleIOWatchEx(const AuSPtr &object, const AuSPtr &listener, bool singleshot) = 0; + + virtual AuSPtr StartSimpleLSWatch (const AuSPtr &source, const AuSPtr &listener) = 0; + virtual AuSPtr StartSimpleLSWatchEx(const AuSPtr &source, const AuSPtr &listener, bool singleshot, AuUInt32 msTimeout = 0) = 0; virtual bool SubmitIOWorkItem (const AuSPtr &work) = 0; diff --git a/Include/Aurora/IO/IIOWaitableIOLoopSource.hpp b/Include/Aurora/IO/IIOWaitableIOLoopSource.hpp index 3040c2c8..add746ee 100644 --- a/Include/Aurora/IO/IIOWaitableIOLoopSource.hpp +++ b/Include/Aurora/IO/IIOWaitableIOLoopSource.hpp @@ -16,4 +16,5 @@ namespace Aurora::IO }; AUKN_SYM AuSPtr NewWaitableLoopSource(const AuSPtr &ptr); + AUKN_SYM AuSPtr NewWaitableLoopSourceEx(const AuSPtr& ptr, AuUInt32 msTimeout); } \ No newline at end of file diff --git a/Include/Aurora/IO/IIOWaitableItem.hpp b/Include/Aurora/IO/IIOWaitableItem.hpp index e046e0f3..5500fd75 100644 --- a/Include/Aurora/IO/IIOWaitableItem.hpp +++ b/Include/Aurora/IO/IIOWaitableItem.hpp @@ -24,6 +24,7 @@ namespace Aurora::IO AUI_METHOD(bool, IsRunOnSelfIO, ()), AUI_METHOD(AuSPtr, GetSelfIOSource, ()), + AUI_METHOD(AuUInt32, IOTimeoutInMS, ()), AUI_METHOD(bool, IsRunOnSelfIOCheckedOnTimerTick, ()), AUI_METHOD(bool, ApplyRateLimit, ()) diff --git a/README.md b/README.md index 182af2ac..5cd71608 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ ## PREALPHA (in-dev, missing polish and APIs are volatile) +## Minimum viable product ETA: September 2022 ## AuroraRuntime @@ -50,6 +51,18 @@ Build Pipeline: [Aurora Build](https://git.reece.sx/AuroraPipeline/Build) (Lua/P Donate / Other Links: [Reece.SX](https://reece.sx/#contact) \ Discord: [Invite](https://discord.gg/XYjCGWWa4J) +## Support + +| Platform | Support | +| ----------- | ------- | +| NT/Win32-like |✅ | +| NT/UWP | 🕖 | +| NT/GameOS|❌ | +| Linux |🕖 | +| FreeBSD 9 | ❌ | +| FreeBSD 11 | ❌ | +| XNU/NS-like | ❌ | + ## Performance Performance of each system should ideally be that of the best implementation on the platform, diff --git a/Source/IO/IOPipeProcessor.cpp b/Source/IO/IOPipeProcessor.cpp index 09a81efd..b7a0973d 100644 --- a/Source/IO/IOPipeProcessor.cpp +++ b/Source/IO/IOPipeProcessor.cpp @@ -105,6 +105,7 @@ namespace Aurora::IO this->bytesWrittenLimit_ = request.lengthOrZero; this->asyncTransaction_ = request.asyncTransaction; this->asyncAdapter_ = NewAsyncStreamAdapter(request.asyncTransaction, request.isStream); + SysAssert(this->asyncAdapter_); this->asyncStreamReader_ = this->asyncAdapter_->ToStreamReader(); } diff --git a/Source/IO/IOProcessor.cpp b/Source/IO/IOProcessor.cpp index c81cf9aa..855c000c 100644 --- a/Source/IO/IOProcessor.cpp +++ b/Source/IO/IOProcessor.cpp @@ -297,6 +297,8 @@ namespace Aurora::IO } } + auto hasRemoved = this->items.crossThreadAbort.size(); + for (auto itr = this->items.crossThreadAbort.begin(); itr != this->items.crossThreadAbort.end(); ) { bool fatal = itr->second; @@ -307,6 +309,11 @@ namespace Aurora::IO itr = this->items.crossThreadAbort.erase(itr); } + + if (hasRemoved) + { + ToQueue()->Commit(); + } } @@ -618,17 +625,19 @@ namespace Aurora::IO return {}; } - AuSPtr IOProcessor::StartIOWatch(const AuSPtr &object, const AuSPtr &listener) + + AuSPtr IOProcessor::StartIOWatchEx(const AuSPtr& object, const AuSPtr& listener, bool singleshot) { if (!CheckThread()) { AU_THROW_STRING("Wrong Thread"); } - + auto item = AuMakeShared(); item->parent = this; item->listener = listener; item->item = object; + item->singleshot = true; AU_LOCK_GUARD(this->items.mutex); @@ -661,13 +670,25 @@ namespace Aurora::IO return {}; } - if (!this->ToQueue()->SourceAdd(src)) + auto timeout = object->IOTimeoutInMS(); + if (timeout) { - SysPushErrorNested("IO Error"); - return {}; + if (!this->ToQueue()->SourceAddWithTimeout(src, timeout)) + { + SysPushErrorNested("IO Error"); + return {}; + } + } + else + { + if (!this->ToQueue()->SourceAdd(src)) + { + SysPushErrorNested("IO Error"); + return {}; + } } - if (!this->ToQueue()->AddCallback(src, item)) + if (!this->ToQueue()->AddCallbackEx(src, item)) { SysPushErrorNested("IO Error"); SysAssert(this->ToQueue()->SourceRemove(src)); @@ -689,8 +710,8 @@ namespace Aurora::IO return item; } - - AuSPtr IOProcessor::StartSimpleIOWatch(const AuSPtr &object, const AuSPtr &listener) + + AuSPtr IOProcessor::StartSimpleIOWatchEx(const AuSPtr& object, const AuSPtr& listener, bool singleshot) { auto adapater = DesimplifyIOEventListenerAdapater(listener); if (!adapater) @@ -699,19 +720,34 @@ namespace Aurora::IO return {}; } - return this->StartIOWatch(object, adapater); + return this->StartIOWatchEx(object, adapater, singleshot); } - AuSPtr IOProcessor::StartSimpleLSWatch(const AuSPtr &source, const AuSPtr &listener) + AuSPtr IOProcessor::StartSimpleLSWatchEx(const AuSPtr& source, const AuSPtr& listener, bool singleshot, AuUInt32 msTimeout) { - auto sourceAdapter = NewWaitableLoopSource(source); + auto sourceAdapter = NewWaitableLoopSourceEx(source, msTimeout); if (!sourceAdapter) { SysPushErrorMem(); return {}; } - return this->StartSimpleIOWatch(sourceAdapter, listener); + return this->StartSimpleIOWatchEx(sourceAdapter, listener, singleshot); + } + + AuSPtr IOProcessor::StartIOWatch(const AuSPtr &object, const AuSPtr &listener) + { + return StartIOWatchEx(object, listener, false); + } + + AuSPtr IOProcessor::StartSimpleIOWatch(const AuSPtr &object, const AuSPtr &listener) + { + return this->StartSimpleIOWatchEx(object, listener, false); + } + + AuSPtr IOProcessor::StartSimpleLSWatch(const AuSPtr &source, const AuSPtr &listener) + { + return this->StartSimpleLSWatchEx(source, listener, false, 0); } AuSPtr IOProcessor::ToPipeProcessor() diff --git a/Source/IO/IOProcessor.hpp b/Source/IO/IOProcessor.hpp index 116a36e7..4b02e978 100644 --- a/Source/IO/IOProcessor.hpp +++ b/Source/IO/IOProcessor.hpp @@ -67,6 +67,11 @@ namespace Aurora::IO AuSPtr StartSimpleIOWatch(const AuSPtr &object, const AuSPtr &listener) override; AuSPtr StartSimpleLSWatch(const AuSPtr &source, const AuSPtr &listener) override; + AuSPtr StartIOWatchEx (const AuSPtr &object, const AuSPtr &listener, bool singleshot) override; + AuSPtr StartSimpleIOWatchEx(const AuSPtr& object, const AuSPtr& listener, bool singleshot) override; + AuSPtr StartSimpleLSWatchEx(const AuSPtr& source, const AuSPtr& listener, bool singleshot, AuUInt32 msTimeout) override; + + AuSPtr ToPipeProcessor() override; AuSPtr ToQueue() override; diff --git a/Source/IO/IOProcessorItem.cpp b/Source/IO/IOProcessorItem.cpp index 9db7a706..5353b4a5 100644 --- a/Source/IO/IOProcessorItem.cpp +++ b/Source/IO/IOProcessorItem.cpp @@ -36,12 +36,34 @@ namespace Aurora::IO return this->parent->items.ScheduleFinish(AuSharedFromThis(), true); } - bool IOProcessorItem::OnFinished(const AuSPtr &source) + + bool IOProcessorItem::OnFinished(const AuSPtr& source, AuUInt8 pos) { + if (this->singleshot) + { + if (AuExchange(this->triggered, true)) + { + StopWatch(); + return true; + } + } + IOAlert(false); + + if (this->singleshot) + { + StopWatch(); + } + return false; } + void IOProcessorItem::OnTimeout(const AuSPtr& source) + { + SysPushErrorIO("IO Timeout"); + this->FailWatch(); + } + void IOProcessorItem::InvokeManualTick() { IOAlert(true); diff --git a/Source/IO/IOProcessorItem.hpp b/Source/IO/IOProcessorItem.hpp index 5615db72..35a96147 100644 --- a/Source/IO/IOProcessorItem.hpp +++ b/Source/IO/IOProcessorItem.hpp @@ -11,16 +11,19 @@ namespace Aurora::IO { struct IOProcessor; - struct IOProcessorItem : AuLoop::ILoopSourceSubscriber, IIOProcessorItem, AuEnableSharedFromThis + struct IOProcessorItem : AuLoop::ILoopSourceSubscriberEx, IIOProcessorItem, AuEnableSharedFromThis { IOProcessor *parent; + bool singleshot{}; + bool triggered{}; AuSPtr item; AuSPtr listener; // ILoopSourceSubscriber - bool OnFinished(const AuSPtr &source) override; - + bool OnFinished(const AuSPtr &source, AuUInt8 pos) override; + void OnTimeout(const AuSPtr& source) override; + // IIOProcessorItem virtual bool StopWatch() override; virtual bool FailWatch() override; diff --git a/Source/IO/IOWaitableIOLoopSource.cpp b/Source/IO/IOWaitableIOLoopSource.cpp index 63d5e90e..7811ea60 100644 --- a/Source/IO/IOWaitableIOLoopSource.cpp +++ b/Source/IO/IOWaitableIOLoopSource.cpp @@ -16,6 +16,11 @@ namespace Aurora::IO } + IOWatachableIOLoopSource::IOWatachableIOLoopSource(const AuSPtr& source, AuUInt32 ioTimeoutMS) : source(source), ioTimeoutMS(ioTimeoutMS) + { + + } + bool IOWatachableIOLoopSource::IsRunOnOtherTick() { return {}; @@ -66,8 +71,18 @@ namespace Aurora::IO return true; } - AUKN_SYM AuSPtr NewWaitableLoopSource(const AuSPtr &ptr) + AuUInt32 IOWatachableIOLoopSource::IOTimeoutInMS() + { + return this->ioTimeoutMS; + } + + AUKN_SYM AuSPtr NewWaitableLoopSource(const AuSPtr& ptr) { return AuMakeShared(ptr); } + + AUKN_SYM AuSPtr NewWaitableLoopSourceEx(const AuSPtr& ptr, AuUInt32 msTimeout) + { + return AuMakeShared(ptr, msTimeout); + } } \ No newline at end of file diff --git a/Source/IO/IOWaitableIOLoopSource.hpp b/Source/IO/IOWaitableIOLoopSource.hpp index 9cc8c1b2..697f0093 100644 --- a/Source/IO/IOWaitableIOLoopSource.hpp +++ b/Source/IO/IOWaitableIOLoopSource.hpp @@ -11,7 +11,8 @@ namespace Aurora::IO { struct IOWatachableIOLoopSource : IIOWatachableIOLoopSource { - IOWatachableIOLoopSource(const AuSPtr &source); + IOWatachableIOLoopSource(const AuSPtr& source); + IOWatachableIOLoopSource(const AuSPtr& source, AuUInt32 ioTimeoutMS); bool IsRunOnOtherTick() override; bool IsRunOnTick() override; @@ -24,10 +25,12 @@ namespace Aurora::IO bool ApplyRateLimit() override; + AuUInt32 IOTimeoutInMS() override; AuSPtr GetLoopSource() override; AuSPtr SetLoopSource(const AuSPtr &ls) override; bool IsRunOnSelfIOCheckedOnTimerTick() override; AuSPtr source; + AuUInt32 ioTimeoutMS{}; }; } \ No newline at end of file diff --git a/Source/IO/IOWaitableIOTimer.cpp b/Source/IO/IOWaitableIOTimer.cpp index 661637f0..ea38fcc1 100644 --- a/Source/IO/IOWaitableIOTimer.cpp +++ b/Source/IO/IOWaitableIOTimer.cpp @@ -61,6 +61,11 @@ namespace Aurora::IO return false; } + AuUInt32 IOWaitableIOTimer::IOTimeoutInMS() + { + return 0; + } + AuUInt64 IOWaitableIOTimer::SetConstantTick(AuUInt64 ns) { auto old = AuExchange(this->constantTickNs, ns); diff --git a/Source/IO/IOWaitableIOTimer.hpp b/Source/IO/IOWaitableIOTimer.hpp index 3c685619..b05b9587 100644 --- a/Source/IO/IOWaitableIOTimer.hpp +++ b/Source/IO/IOWaitableIOTimer.hpp @@ -26,6 +26,8 @@ namespace Aurora::IO bool IsRunOnSelfIOCheckedOnTimerTick() override; bool ApplyRateLimit() override; + AuUInt32 IOTimeoutInMS() override; + AuUInt64 SetConstantTick(AuUInt64 ns) override; AuUInt64 SetTargetTimeAbs(AuUInt64 ns) override;