[+] IIOSimpleEventListener
[+] IOProcessor::StartSimpleIOWatch(const AuSPtr<IIOWaitableItem> &object, const AuSPtr<IIOSimpleEventListener> &listener) [+] IOProcessor::StartSimpleLSWatch(const AuSPtr<Loop::ILoopSource> &source, const AuSPtr<IIOSimpleEventListener> &listener) [*] IOAdapterAsyncStream should reset the transactions IO state upon reaching end of segment (should this be per tick?) or upon stream error - otherwise, we end up spinning on a stuck event forever [*] Fix non-linear path under read of the AuByteBuffer [*] Fix various other nonlinear conditions under AuByteBuffer [*] IOProcessor releases registered io item from queue upon request [*] Fix ConsoleMessage::Write -> enumeration of color should be casted to a uint8 [+] Error telemetry under async task creation [*] Fix various lock ups and non-blocking spins related to erroneous InternalRunOne impl. Residual preemptive batching was fucking with modern io. [*] Cleanup TaskFrom/JobFrom. More work required to clean up legacy piss
This commit is contained in:
parent
7ea75b4014
commit
0c3344fe46
@ -21,7 +21,7 @@ namespace Aurora::Async
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid, class Callable_t>
|
template<class Info_t = AVoid, class Result_t = AVoid, class Callable_t>
|
||||||
static inline FJob<Info_t, Result_t> JobFromResultConsumer(/*AuConsumer<const Result_t &> */ Callable_t&&onSuccess)
|
static inline FJob<Info_t, Result_t> JobFromResultConsumer(/*AuConsumer<const Result_t &> */ Callable_t onSuccess)
|
||||||
{
|
{
|
||||||
FJob<Info_t, Result_t> ret;
|
FJob<Info_t, Result_t> ret;
|
||||||
ret.onSuccess = [=](const Info_t &in, const Result_t &a)
|
ret.onSuccess = [=](const Info_t &in, const Result_t &a)
|
||||||
@ -32,7 +32,7 @@ namespace Aurora::Async
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Out_t = AVoid, typename ... Args, typename Callable_t>
|
template<typename Out_t = AVoid, typename ... Args, typename Callable_t>
|
||||||
FJob<AuTuple<Args...>, Out_t> JobFromTupleConsumer(/*AuConsumer<Args..., const Result_t &> */ Callable_t &&onSuccess)
|
FJob<AuTuple<Args...>, Out_t> JobFromTupleConsumer(/*AuConsumer<Args..., const Result_t &> */ Callable_t onSuccess)
|
||||||
{
|
{
|
||||||
FJob<AuTuple<Args...>, Out_t> ret;
|
FJob<AuTuple<Args...>, Out_t> ret;
|
||||||
ret.onSuccess = [=](const AuTuple<Args...> &in, const Out_t &a)
|
ret.onSuccess = [=](const AuTuple<Args...> &in, const Out_t &a)
|
||||||
@ -43,7 +43,7 @@ namespace Aurora::Async
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Out_t = AVoid, typename ... Args, typename Callable_t, typename FailureCallable_t>
|
template<typename Out_t = AVoid, typename ... Args, typename Callable_t, typename FailureCallable_t>
|
||||||
FJob<AuTuple<Args...>, Out_t> JobFromTupleConsumerEx(/*AuConsumer<Args..., const Result_t &> */ Callable_t &&onSuccess, FailureCallable_t &&onFailure)
|
FJob<AuTuple<Args...>, Out_t> JobFromTupleConsumerEx(/*AuConsumer<Args..., const Result_t &> */ Callable_t onSuccess, FailureCallable_t onFailure)
|
||||||
{
|
{
|
||||||
FJob<AuTuple<Args...>, Out_t> ret;
|
FJob<AuTuple<Args...>, Out_t> ret;
|
||||||
ret.onSuccess = [=](const AuTuple<Args...> &in, const Out_t &a)
|
ret.onSuccess = [=](const AuTuple<Args...> &in, const Out_t &a)
|
||||||
|
@ -10,37 +10,37 @@
|
|||||||
namespace Aurora::Async
|
namespace Aurora::Async
|
||||||
{
|
{
|
||||||
template<typename Info_t = AVoid, typename Out_t = AVoid, class ClazzImpl>
|
template<typename Info_t = AVoid, typename Out_t = AVoid, class ClazzImpl>
|
||||||
FTask<Info_t, Out_t> TaskFromConsumerRefT(ClazzImpl &&func)
|
FTask<Info_t, Out_t> TaskFromConsumerRefT(ClazzImpl func)
|
||||||
{
|
{
|
||||||
FTask<Info_t, Out_t> ret;
|
FTask<Info_t, Out_t> ret;
|
||||||
ret.onFrame = [callable = func](const Info_t &in) -> Out_t
|
ret.onFrame = [=](const Info_t &in) -> Out_t
|
||||||
{
|
{
|
||||||
if constexpr (AuIsSame_v<Out_t, AVoid>)
|
if constexpr (AuIsSame_v<Out_t, AVoid>)
|
||||||
{
|
{
|
||||||
callable(in);
|
func(in);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return callable(in);
|
return func(in);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Out_t = AVoid, typename ... Args, typename Functor>
|
template<typename Out_t = AVoid, typename ... Args, typename Functor>
|
||||||
FTask<AuTuple<Args...>, Out_t> TaskFromTupleCallable(Functor &&func)
|
FTask<AuTuple<Args...>, Out_t> TaskFromTupleCallable(Functor func)
|
||||||
{
|
{
|
||||||
FTask<AuTuple<Args...>, Out_t> ret;
|
FTask<AuTuple<Args...>, Out_t> ret;
|
||||||
ret.onFrame = [callable = func](const AuTuple<Args...> &in) -> Out_t
|
ret.onFrame = [=](const AuTuple<Args...> &in) -> Out_t
|
||||||
{
|
{
|
||||||
return AuTupleApply(callable, in);
|
return AuTupleApply(func, in);
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Out_t = AVoid, typename Owner_t, typename ... Args>
|
template<typename Out_t = AVoid, typename Owner_t, typename ... Args>
|
||||||
FTask<AuTuple<Args...>, Out_t> TaskFromTupleCallableWithOwnerArg(AuFunction<Out_t(Args...)> &&func, const Owner_t &ownerToPin)
|
FTask<AuTuple<Args...>, Out_t> TaskFromTupleCallableWithOwnerArg(AuFunction<Out_t(Args...)> func, const Owner_t &ownerToPin)
|
||||||
{
|
{
|
||||||
FTask<AuTuple<Owner_t, Args...>, Out_t> ret;
|
FTask<AuTuple<Owner_t, Args...>, Out_t> ret;
|
||||||
ret.onFrame = [ownerToPin, callable = func](const AuTuple<Args...> &in) -> Out_t
|
ret.onFrame = [ownerToPin, callable = func](const AuTuple<Args...> &in) -> Out_t
|
||||||
@ -51,12 +51,12 @@ namespace Aurora::Async
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Task_t, typename ReturnValue_t, typename ... Args, typename Functor>
|
template<typename Task_t, typename ReturnValue_t, typename ... Args, typename Functor>
|
||||||
Task_t TaskFromTupleCallableWithBindOwner(Functor &&func)
|
Task_t TaskFromTupleCallableWithBindOwner(Functor func)
|
||||||
{
|
{
|
||||||
Task_t ret;
|
Task_t ret;
|
||||||
ret.onFrame = [callable = func](const auto &in) -> ReturnValue_t
|
ret.onFrame = [=](const auto &in) -> ReturnValue_t
|
||||||
{
|
{
|
||||||
return AuTupleApply(callable, AuTuplePopFront(in));
|
return AuTupleApply(func, AuTuplePopFront(in));
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -65,9 +65,9 @@ namespace Aurora::Async
|
|||||||
Task_t TaskFromTupleCallableWithBindOwner2(Functor func)
|
Task_t TaskFromTupleCallableWithBindOwner2(Functor func)
|
||||||
{
|
{
|
||||||
Task_t ret;
|
Task_t ret;
|
||||||
ret.onFrame = [callable = func](const auto &in) -> ReturnValue_t
|
ret.onFrame = [=](const auto &in) -> ReturnValue_t
|
||||||
{
|
{
|
||||||
return AuTupleApply(callable, AuTuplePopFront(in));
|
return AuTupleApply(func, AuTuplePopFront(in));
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
namespace Aurora::IO
|
namespace Aurora::IO
|
||||||
{
|
{
|
||||||
AUKN_INTERFACE(IIOEventListener,
|
AUKN_INTERFACE(IIOEventListener,
|
||||||
AUI_METHOD(void, Tick_RunOnTick, ()), // called on each tick, if registered by the iWaitableitem interface
|
AUI_METHOD(void, Tick_RunOnTick, ()), // called on each tick, if registered by the IWaitableItem interface
|
||||||
|
|
||||||
AUI_METHOD(void, Tick_OtherIOEvent, ()), // called if a different object woke us up
|
AUI_METHOD(void, Tick_OtherIOEvent, ()), // called if a different object woke us up
|
||||||
AUI_METHOD(void, Tick_SelfIOEvent, ()), // called if a ticker, io loop source, or other self-iWaitableitem interface poked us
|
AUI_METHOD(void, Tick_SelfIOEvent, ()), // called if a ticker, io loop source, or other self-iWaitableitem interface poked us
|
||||||
|
@ -25,6 +25,8 @@ namespace Aurora::IO
|
|||||||
virtual AuUInt64 GetOwnedThreadId () = 0;
|
virtual AuUInt64 GetOwnedThreadId () = 0;
|
||||||
|
|
||||||
virtual AuSPtr<IIOProcessorItem> StartIOWatch (const AuSPtr<IIOWaitableItem> &object, const AuSPtr<IIOEventListener> &listener) = 0;
|
virtual AuSPtr<IIOProcessorItem> StartIOWatch (const AuSPtr<IIOWaitableItem> &object, const AuSPtr<IIOEventListener> &listener) = 0;
|
||||||
|
virtual AuSPtr<IIOProcessorItem> StartSimpleIOWatch (const AuSPtr<IIOWaitableItem> &object, const AuSPtr<IIOSimpleEventListener> &listener) = 0;
|
||||||
|
virtual AuSPtr<IIOProcessorItem> StartSimpleLSWatch (const AuSPtr<Loop::ILoopSource> &source, const AuSPtr<IIOSimpleEventListener> &listener) = 0;
|
||||||
|
|
||||||
virtual bool SubmitIOWorkItem (const AuSPtr<IIOProcessorWorkUnit> &work) = 0;
|
virtual bool SubmitIOWorkItem (const AuSPtr<IIOProcessorWorkUnit> &work) = 0;
|
||||||
|
|
||||||
|
19
Include/Aurora/IO/IIOSimpleEventListener.hpp
Normal file
19
Include/Aurora/IO/IIOSimpleEventListener.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: IIOSimpleEventListener.hpp
|
||||||
|
Date: 2022-6-22
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO
|
||||||
|
{
|
||||||
|
AUKN_INTERFACE(IIOSimpleEventListener,
|
||||||
|
AUI_METHOD(void, OnIOTick, ()),
|
||||||
|
AUI_METHOD(void, OnIOFailure, ()),
|
||||||
|
AUI_METHOD(void, OnIOComplete, ())
|
||||||
|
);
|
||||||
|
|
||||||
|
AUKN_SYM AuSPtr<IIOEventListener> DesimplifyIOEventListenerAdapater(const AuSPtr<IIOSimpleEventListener> &interface);
|
||||||
|
}
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "IIOWaitableItem.hpp"
|
#include "IIOWaitableItem.hpp"
|
||||||
#include "IIOEventListener.hpp"
|
#include "IIOEventListener.hpp"
|
||||||
|
#include "IIOSimpleEventListener.hpp"
|
||||||
|
|
||||||
#include "EIOProcessorEventStage.hpp"
|
#include "EIOProcessorEventStage.hpp"
|
||||||
#include "IIOPipeEventListener.hpp"
|
#include "IIOPipeEventListener.hpp"
|
||||||
|
@ -59,6 +59,10 @@ namespace Aurora::Memory
|
|||||||
{
|
{
|
||||||
linearOverhead = readPtr - writePtr;
|
linearOverhead = readPtr - writePtr;
|
||||||
}
|
}
|
||||||
|
else if (writePtr == readPtr)
|
||||||
|
{
|
||||||
|
linearOverhead = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linearOverhead = length - (writePtr - base);
|
linearOverhead = length - (writePtr - base);
|
||||||
@ -134,7 +138,11 @@ namespace Aurora::Memory
|
|||||||
{
|
{
|
||||||
if (flagCircular)
|
if (flagCircular)
|
||||||
{
|
{
|
||||||
if ((readPtr < writePtr) && (endAtWrite))
|
if (readPtr == writePtr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if ((readPtr < writePtr) && (endAtWrite))
|
||||||
{
|
{
|
||||||
return writePtr - readPtr;
|
return writePtr - readPtr;
|
||||||
}
|
}
|
||||||
@ -169,7 +177,11 @@ namespace Aurora::Memory
|
|||||||
{
|
{
|
||||||
if (flagCircular)
|
if (flagCircular)
|
||||||
{
|
{
|
||||||
if ((writePtr < readPtr) && (endAtRead))
|
if (readPtr == writePtr)
|
||||||
|
{
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
else if ((writePtr < readPtr) && (endAtRead))
|
||||||
{
|
{
|
||||||
return readPtr - writePtr;
|
return readPtr - writePtr;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,12 @@ namespace Aurora::Memory
|
|||||||
AuUInt linearOverhead = 0, toWriteOverhead = 0, linearReadable = 0, toWriteReadable = 0;
|
AuUInt linearOverhead = 0, toWriteOverhead = 0, linearReadable = 0, toWriteReadable = 0;
|
||||||
if (flagCircular)
|
if (flagCircular)
|
||||||
{
|
{
|
||||||
if (readPtr < writePtr)
|
if (readPtr == writePtr)
|
||||||
|
{
|
||||||
|
linearOverhead = 0;
|
||||||
|
toWriteOverhead = 0;
|
||||||
|
}
|
||||||
|
else if (readPtr < writePtr)
|
||||||
{
|
{
|
||||||
linearOverhead = writePtr - readPtr;
|
linearOverhead = writePtr - readPtr;
|
||||||
toWriteOverhead = 0;
|
toWriteOverhead = 0;
|
||||||
@ -131,12 +136,12 @@ namespace Aurora::Memory
|
|||||||
|
|
||||||
if (out)
|
if (out)
|
||||||
{
|
{
|
||||||
AuMemcpy(out, readPtr, linearOverhead);
|
AuMemcpy(out, readPtr, linearReadable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!peek)
|
if (!peek)
|
||||||
{
|
{
|
||||||
readPtr += linearOverhead;
|
readPtr += linearReadable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toWriteOverhead)
|
if (toWriteOverhead)
|
||||||
|
@ -252,7 +252,7 @@ namespace Aurora::Async
|
|||||||
bool success {};
|
bool success {};
|
||||||
auto runMode = GetCurrentThreadRunMode();
|
auto runMode = GetCurrentThreadRunMode();
|
||||||
|
|
||||||
do
|
//do
|
||||||
{
|
{
|
||||||
auto asyncLoop = state->asyncLoop;
|
auto asyncLoop = state->asyncLoop;
|
||||||
|
|
||||||
@ -304,11 +304,12 @@ namespace Aurora::Async
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bShouldTrySleepForKernel
|
if (bShouldTrySleepForKernel
|
||||||
// epoll and such like can be checked without read success. kevent works on availablity, not scheduling read like iosubmit, too.
|
// epoll and such like can be checked without read success. kevent works on availablity, not scheduling read like iosubmit
|
||||||
// allow windows to atomically pump instead of wasting time buffering the primitives state
|
// allow windows to atomically pump instead of wasting time buffering the primitives state
|
||||||
#if defined(AURORA_PLATFORM_WIN32)
|
&& ((AuBuild::kIsNtDerived && runMode == ERunMode::eEfficient) ||
|
||||||
&& asyncLoop->WaitAny(0)
|
(!AuBuild::kIsNtDerived))
|
||||||
#endif
|
|
||||||
|
&& (asyncLoop->WaitAny(0))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PollInternal(block);
|
PollInternal(block);
|
||||||
@ -323,7 +324,7 @@ namespace Aurora::Async
|
|||||||
{
|
{
|
||||||
success = PollInternal(block);
|
success = PollInternal(block);
|
||||||
}
|
}
|
||||||
} while (success);
|
} //while (success);
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -946,6 +947,7 @@ namespace Aurora::Async
|
|||||||
threadState->id = workerId;
|
threadState->id = workerId;
|
||||||
threadState->asyncLoop = AuMakeShared<AsyncLoop>();
|
threadState->asyncLoop = AuMakeShared<AsyncLoop>();
|
||||||
threadState->rateLimiter.SetNextStep(1'000'000); // 1MS in nanoseconds
|
threadState->rateLimiter.SetNextStep(1'000'000); // 1MS in nanoseconds
|
||||||
|
threadState->runMode = ERunMode::eEfficient;
|
||||||
|
|
||||||
if (!threadState->asyncLoop)
|
if (!threadState->asyncLoop)
|
||||||
{
|
{
|
||||||
|
@ -384,6 +384,7 @@ namespace Aurora::Async
|
|||||||
{
|
{
|
||||||
if (!task)
|
if (!task)
|
||||||
{
|
{
|
||||||
|
SysPushErrorArg("WorkItem has null task. Running out of memory?");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,11 +395,13 @@ namespace Aurora::Async
|
|||||||
{
|
{
|
||||||
if (!task)
|
if (!task)
|
||||||
{
|
{
|
||||||
|
SysPushErrorArg("WorkItem has null task. Running out of memory?");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!worker.pool)
|
if (!worker.pool)
|
||||||
{
|
{
|
||||||
|
SysPushErrorArg("WorkItem has null pool");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ namespace Aurora::Console::Commands
|
|||||||
|
|
||||||
if (type == EDispatchType::eSys)
|
if (type == EDispatchType::eSys)
|
||||||
{
|
{
|
||||||
gPendingCommands.push_back(CommandDispatch(res.result, cmdEntry.callback));
|
return AuTryInsert(gPendingCommands, CommandDispatch(res.result, cmdEntry.callback));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -122,12 +122,13 @@ namespace Aurora::Console::Commands
|
|||||||
AUKN_SYM void AddCommand(const AuString &tag, const Parse::ParseObject &commandStructure, const AuSPtr<ICommandSubscriber> &callback)
|
AUKN_SYM void AddCommand(const AuString &tag, const Parse::ParseObject &commandStructure, const AuSPtr<ICommandSubscriber> &callback)
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(gPendingCommandsMutex);
|
AU_LOCK_GUARD(gPendingCommandsMutex);
|
||||||
|
SysAssert(callback);
|
||||||
gCommands.insert(AuMakePair(tag, Command(tag, commandStructure, callback)));
|
gCommands.insert(AuMakePair(tag, Command(tag, commandStructure, callback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM bool DispatchCommand(const AuString &string)
|
AUKN_SYM bool DispatchCommand(const AuString &string)
|
||||||
{
|
{
|
||||||
return Dispatch(string, EDispatchType::eSys, {});
|
return Dispatch(string, EDispatchType::eSys, gCommandDispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM bool DispatchCommandThisThread(const AuString &string)
|
AUKN_SYM bool DispatchCommandThisThread(const AuString &string)
|
||||||
|
@ -47,7 +47,7 @@ namespace Aurora::Console
|
|||||||
|
|
||||||
AUKN_SYM void ConsoleMessage::Write(Memory::ByteBuffer &serialize) const
|
AUKN_SYM void ConsoleMessage::Write(Memory::ByteBuffer &serialize) const
|
||||||
{
|
{
|
||||||
serialize.Write(static_cast<EAnsiColor>(color));
|
serialize.Write(static_cast<AuUInt8>(color));
|
||||||
serialize.Write(prefix);
|
serialize.Write(prefix);
|
||||||
serialize.Write(line);
|
serialize.Write(line);
|
||||||
serialize.Write(time);
|
serialize.Write(time);
|
||||||
|
@ -717,7 +717,7 @@ namespace Aurora::Console::ConsoleTTY
|
|||||||
int XOffset = GetLeftBorder() + this->leftLogPadding;
|
int XOffset = GetLeftBorder() + this->leftLogPadding;
|
||||||
|
|
||||||
auto itr = str.npos;
|
auto itr = str.npos;
|
||||||
itr = str.find('\t', itr);
|
itr = str.find('\t');
|
||||||
|
|
||||||
while (itr != str.npos)
|
while (itr != str.npos)
|
||||||
{
|
{
|
||||||
|
@ -274,6 +274,7 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
if (code != EStreamError::eErrorNone)
|
if (code != EStreamError::eErrorNone)
|
||||||
{
|
{
|
||||||
|
parent->transaction->Reset();
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,6 +306,11 @@ namespace Aurora::IO
|
|||||||
{
|
{
|
||||||
parent->readOffset += out.length;
|
parent->readOffset += out.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parent->lastAllocation->streamIndex == length)
|
||||||
|
{
|
||||||
|
parent->transaction->Reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EStreamError::eErrorNone;
|
return EStreamError::eErrorNone;
|
||||||
|
@ -407,9 +407,9 @@ namespace Aurora::IO
|
|||||||
this->bShouldReadNext = true;
|
this->bShouldReadNext = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->output.forwardStream.bFlushWriter)
|
|
||||||
{
|
|
||||||
if (this->output.type == EPipeCallbackType::eWriteToWriter)
|
if (this->output.type == EPipeCallbackType::eWriteToWriter)
|
||||||
|
{
|
||||||
|
if (this->output.forwardStream.bFlushWriter)
|
||||||
{
|
{
|
||||||
this->output.forwardStream.writer->Flush();
|
this->output.forwardStream.writer->Flush();
|
||||||
}
|
}
|
||||||
|
@ -690,6 +690,30 @@ namespace Aurora::IO
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuSPtr<IIOProcessorItem> IOProcessor::StartSimpleIOWatch(const AuSPtr<IIOWaitableItem> &object, const AuSPtr<IIOSimpleEventListener> &listener)
|
||||||
|
{
|
||||||
|
auto adapater = DesimplifyIOEventListenerAdapater(listener);
|
||||||
|
if (!adapater)
|
||||||
|
{
|
||||||
|
SysPushErrorMem();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->StartIOWatch(object, adapater);
|
||||||
|
}
|
||||||
|
|
||||||
|
AuSPtr<IIOProcessorItem> IOProcessor::StartSimpleLSWatch(const AuSPtr<Loop::ILoopSource> &source, const AuSPtr<IIOSimpleEventListener> &listener)
|
||||||
|
{
|
||||||
|
auto sourceAdapter = NewWaitableLoopSource(source);
|
||||||
|
if (!sourceAdapter)
|
||||||
|
{
|
||||||
|
SysPushErrorMem();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->StartSimpleIOWatch(sourceAdapter, listener);
|
||||||
|
}
|
||||||
|
|
||||||
AuSPtr<IIOPipeProcessor> IOProcessor::ToPipeProcessor()
|
AuSPtr<IIOPipeProcessor> IOProcessor::ToPipeProcessor()
|
||||||
{
|
{
|
||||||
if (!CheckThread())
|
if (!CheckThread())
|
||||||
@ -716,6 +740,11 @@ namespace Aurora::IO
|
|||||||
queue->SourceRemove(this->items.cvEvent);
|
queue->SourceRemove(this->items.cvEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &io : this->items.registeredIO)
|
||||||
|
{
|
||||||
|
queue->SourceRemove(io->item->GetSelfIOSource());
|
||||||
|
}
|
||||||
|
|
||||||
queue->Commit();
|
queue->Commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,8 @@ namespace Aurora::IO
|
|||||||
bool MultiplexRefreshRateWithIOEvents() override;
|
bool MultiplexRefreshRateWithIOEvents() override;
|
||||||
|
|
||||||
AuSPtr<IIOProcessorItem> StartIOWatch(const AuSPtr<IIOWaitableItem> &object, const AuSPtr<IIOEventListener> &listener) override;
|
AuSPtr<IIOProcessorItem> StartIOWatch(const AuSPtr<IIOWaitableItem> &object, const AuSPtr<IIOEventListener> &listener) override;
|
||||||
|
AuSPtr<IIOProcessorItem> StartSimpleIOWatch(const AuSPtr<IIOWaitableItem> &object, const AuSPtr<IIOSimpleEventListener> &listener) override;
|
||||||
|
AuSPtr<IIOProcessorItem> StartSimpleLSWatch(const AuSPtr<Loop::ILoopSource> &source, const AuSPtr<IIOSimpleEventListener> &listener) override;
|
||||||
|
|
||||||
AuSPtr<IIOPipeProcessor> ToPipeProcessor() override;
|
AuSPtr<IIOPipeProcessor> ToPipeProcessor() override;
|
||||||
|
|
||||||
|
63
Source/IO/IOSimpleEventListener.cpp
Normal file
63
Source/IO/IOSimpleEventListener.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: IOSimpleEventListener.cpp
|
||||||
|
Date: 2022-6-22
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#include <Source/RuntimeInternal.hpp>
|
||||||
|
#include <Aurora/IO/IOExperimental.hpp>
|
||||||
|
#include "IOSimpleEventListener.hpp"
|
||||||
|
|
||||||
|
namespace Aurora::IO
|
||||||
|
{
|
||||||
|
IOSimpleEventListener::IOSimpleEventListener(const AuSPtr<IIOSimpleEventListener> &parent) : parent(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSimpleEventListener::Tick_RunOnTick()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSimpleEventListener::Tick_OtherIOEvent()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSimpleEventListener::Tick_SelfIOEvent()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSimpleEventListener::Tick_Any()
|
||||||
|
{
|
||||||
|
this->parent->OnIOTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSimpleEventListener::Tick_FrameEpilogue()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSimpleEventListener::OnFailureCompletion()
|
||||||
|
{
|
||||||
|
this->parent->OnIOFailure();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSimpleEventListener::OnNominalCompletion()
|
||||||
|
{
|
||||||
|
this->parent->OnIOComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuSPtr<IIOEventListener> DesimplifyIOEventListenerAdapater(const AuSPtr<IIOSimpleEventListener> &interface)
|
||||||
|
{
|
||||||
|
if (!interface)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return AuMakeShared<IOSimpleEventListener>(interface);
|
||||||
|
}
|
||||||
|
}
|
26
Source/IO/IOSimpleEventListener.hpp
Normal file
26
Source/IO/IOSimpleEventListener.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: IOSimpleEventListener.hpp
|
||||||
|
Date: 2022-6-22
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO
|
||||||
|
{
|
||||||
|
struct IOSimpleEventListener : IIOEventListener
|
||||||
|
{
|
||||||
|
IOSimpleEventListener(const AuSPtr<IIOSimpleEventListener> &parent);
|
||||||
|
|
||||||
|
void Tick_RunOnTick() override;
|
||||||
|
void Tick_OtherIOEvent() override;
|
||||||
|
void Tick_SelfIOEvent() override;
|
||||||
|
void Tick_Any() override;
|
||||||
|
void Tick_FrameEpilogue() override;
|
||||||
|
void OnFailureCompletion() override;
|
||||||
|
void OnNominalCompletion() override;
|
||||||
|
|
||||||
|
AuSPtr<IIOSimpleEventListener> parent;
|
||||||
|
};
|
||||||
|
}
|
@ -22,7 +22,7 @@ namespace Aurora::IO::IPC
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
struct IPCPipeImpl;
|
struct IPCPipeImpl;
|
||||||
|
|
||||||
struct IPCHasConnectionEvent : Loop::LSEvent
|
struct IPCHasConnectionEvent : Loop::LSHandle
|
||||||
{
|
{
|
||||||
IPCHasConnectionEvent(AuSPtr<IPCPipeImpl> parent);
|
IPCHasConnectionEvent(AuSPtr<IPCPipeImpl> parent);
|
||||||
|
|
||||||
@ -56,22 +56,26 @@ namespace Aurora::IO::IPC
|
|||||||
Loop::ELoopSource GetType() override;
|
Loop::ELoopSource GetType() override;
|
||||||
|
|
||||||
HANDLE GetPipeHandle();
|
HANDLE GetPipeHandle();
|
||||||
|
HANDLE GetConnectHandle()
|
||||||
|
{
|
||||||
|
return (HANDLE)AuStaticCast<Loop::LSEvent>(this->hasClient_)->GetHandle();
|
||||||
|
}
|
||||||
|
|
||||||
void TryConnect();
|
void TryConnect();
|
||||||
OVERLAPPED overlapped {};
|
OVERLAPPED overlapped {};
|
||||||
|
|
||||||
|
AuSPtr<Loop::ILSEvent> hasClient_;
|
||||||
private:
|
private:
|
||||||
HANDLE serverHandle_ {INVALID_HANDLE_VALUE};
|
HANDLE serverHandle_ {INVALID_HANDLE_VALUE};
|
||||||
HANDLE clientHandle_ {INVALID_HANDLE_VALUE};
|
HANDLE clientHandle_ {INVALID_HANDLE_VALUE};
|
||||||
IPCHandle ipcHandle_;
|
IPCHandle ipcHandle_;
|
||||||
AuSPtr<IO::FS::FileHandle> fsHandle_;
|
AuSPtr<IO::FS::FileHandle> fsHandle_;
|
||||||
AuSPtr<IO::FS::NtAsyncFileStream> fsStream_;
|
AuSPtr<IO::FS::NtAsyncFileStream> fsStream_;
|
||||||
AuSPtr<Loop::ILSEvent> hasClient_;
|
|
||||||
AuSPtr<IPCHasConnectionEvent> lshasConnection_;
|
AuSPtr<IPCHasConnectionEvent> lshasConnection_;
|
||||||
bool bFirstTime {true};
|
bool bFirstTime {true};
|
||||||
};
|
};
|
||||||
|
|
||||||
IPCHasConnectionEvent::IPCHasConnectionEvent(AuSPtr<IPCPipeImpl> parent) : parent_(parent), LSEvent(false, false, true)
|
IPCHasConnectionEvent::IPCHasConnectionEvent(AuSPtr<IPCPipeImpl> parent) : parent_(parent), LSHandle((AuUInt)parent->GetConnectHandle())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -126,7 +130,7 @@ namespace Aurora::IO::IPC
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->overlapped.hEvent = (HANDLE)AuStaticCast<Loop::LSEvent>(this->hasClient_)->GetHandle();
|
this->overlapped.hEvent = GetConnectHandle();
|
||||||
|
|
||||||
bool firstTime = AuExchange(bFirstTime, false);
|
bool firstTime = AuExchange(bFirstTime, false);
|
||||||
if (firstTime ||
|
if (firstTime ||
|
||||||
@ -175,7 +179,7 @@ namespace Aurora::IO::IPC
|
|||||||
this->lshasConnection_ = AuMakeShared<IPCHasConnectionEvent>(AuSharedFromThis());
|
this->lshasConnection_ = AuMakeShared<IPCHasConnectionEvent>(AuSharedFromThis());
|
||||||
}
|
}
|
||||||
|
|
||||||
return AuStaticCast<Loop::ILSEvent>(this->lshasConnection_);
|
return this->lshasConnection_;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<Loop::ILoopSource> IPCPipeImpl::AsReadChannelHasData()
|
AuSPtr<Loop::ILoopSource> IPCPipeImpl::AsReadChannelHasData()
|
||||||
|
Loading…
Reference in New Issue
Block a user