From 3472665c9fb0d597debf2cc633f86a3fbd13e61a Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Thu, 5 Sep 2024 18:20:12 +0100 Subject: [PATCH] [+] AuOutputOfs OutputOfResult should have a lock for multithread consumption --- Include/Aurora/Processes/OutputOf.hpp | 22 +++++++++++++------- Source/Processes/AuOutputOf.cpp | 30 +++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/Include/Aurora/Processes/OutputOf.hpp b/Include/Aurora/Processes/OutputOf.hpp index bd6ae581..49475ed5 100644 --- a/Include/Aurora/Processes/OutputOf.hpp +++ b/Include/Aurora/Processes/OutputOf.hpp @@ -18,12 +18,16 @@ namespace Aurora::Processes struct OutputOfResult { - bool bFailed {}; - bool bNoStart {}; - AuString strStdout; - AuString strStderr; - AuUInt uExitCode {}; - AuSInt sExitCode {}; + // Lockable object for reading strStdout and strStderr between threads. + /*AuFutexMutex*/ Aurora::Threading::Waitables::FutexWaitableNoVTblMovable lock; + bool bFailed { }; + bool bNoStart { }; + bool bPipeOutOOM { }; + bool bPipeErrOOM { }; + AuString strStdout { }; + AuString strStderr { }; + AuUInt uExitCode { }; + AuSInt sExitCode { }; }; struct IAsyncOutputOf @@ -39,9 +43,13 @@ namespace Aurora::Processes AURT_ADD_USR_DATA_EXP(this->ToCompletionGroupHandle()); }; + // Thread-local blocking AUKN_SYM OutputOfResult OutputOf(StartupParameters &¶meters, - AuOptional toSend); + AuOptional toSend /* TODO: not yet implemented */); + // Thread-local async + // See: IOSleep.hpp, other ILoopSource yields to enter an alertable state, ILoopQueue to enter an alertable state, et al. + // Will attach to a async worker thread, if under an AuAsync thread. AUKN_SYM AuSPtr OutputOfAsync(StartupParameters &¶meters, const AuSPtr &pCallbacks); } \ No newline at end of file diff --git a/Source/Processes/AuOutputOf.cpp b/Source/Processes/AuOutputOf.cpp index 8fbf77b9..7dfe2ecc 100644 --- a/Source/Processes/AuOutputOf.cpp +++ b/Source/Processes/AuOutputOf.cpp @@ -612,7 +612,20 @@ namespace Aurora::Processes if (length) { - pResult->result.strStdout += AuString(pResult->stdOutPipe.begin(), pResult->stdOutPipe.begin() + length); + try + { + AU_LOCK_GUARD(pResult->result.lock); + pResult->result.strStdout += AuString(pResult->stdOutPipe.begin(), pResult->stdOutPipe.begin() + length); + } + catch (...) + { + SysPushErrorOutOfSpaceMemory(); + pResult->result.bPipeOutOOM = true; + AuResetMember(pResult->pTransactionA); + AuResetMember(pResult->pTransactionSourceA); + return; + } + if (pResult->pCallbacks) { pResult->pCallbacks->OnPipeData(); @@ -641,7 +654,20 @@ namespace Aurora::Processes if (length) { - pResult->result.strStderr += AuString(pResult->stdErrPipe.begin(), pResult->stdErrPipe.begin() + length); + try + { + AU_LOCK_GUARD(pResult->result.lock); + pResult->result.strStderr += AuString(pResult->stdErrPipe.begin(), pResult->stdErrPipe.begin() + length); + } + catch (...) + { + SysPushErrorOutOfSpaceMemory(); + pResult->result.bPipeErrOOM = true; + AuResetMember(pResult->pTransactionB); + AuResetMember(pResult->pTransactionSourceB); + return; + } + if (pResult->pCallbacks) { pResult->pCallbacks->OnPipeData();