From 97cdbc9f27ba81ec66874cc06fa1e0d232745a1b Mon Sep 17 00:00:00 2001 From: Reece Date: Tue, 3 May 2022 11:10:04 +0100 Subject: [PATCH] [+] Overlapped stdout/in/err processes API --- Include/Aurora/Processes/IProcess.hpp | 12 ++++++ Source/IO/FS/Async.NT.cpp | 13 ++++-- Source/IO/FS/Async.NT.hpp | 4 +- Source/IPC/IPCPipe.NT.cpp | 2 +- Source/IPC/IPCPipe.Unix.cpp | 2 +- Source/Processes/Process.NT.cpp | 60 +++++++++++++++++++++++++-- Source/Processes/Process.NT.hpp | 15 ++++++- 7 files changed, 95 insertions(+), 13 deletions(-) diff --git a/Include/Aurora/Processes/IProcess.hpp b/Include/Aurora/Processes/IProcess.hpp index 19225b50..472ee078 100644 --- a/Include/Aurora/Processes/IProcess.hpp +++ b/Include/Aurora/Processes/IProcess.hpp @@ -76,5 +76,17 @@ namespace Aurora::Processes * @return */ virtual bool Write(const Memory::MemoryViewStreamRead &source) = 0; + + /** + * @brief Returns a asynchronous file stream transaction of pipe pair: stdout, stdin + * @return + */ + virtual AuSPtr NewAsyncTransaction() = 0; + + /** + * @brief Returns a asynchronous file stream transaction of pipe pair: stdout, INVALID + * @return + */ + virtual AuSPtr NewErrorStreamAsyncTransaction() = 0; }; } \ No newline at end of file diff --git a/Source/IO/FS/Async.NT.cpp b/Source/IO/FS/Async.NT.cpp index a6a67e06..2efb6369 100644 --- a/Source/IO/FS/Async.NT.cpp +++ b/Source/IO/FS/Async.NT.cpp @@ -51,6 +51,11 @@ namespace Aurora::IO::FS FileHandle::~FileHandle() { + if (this->writeHandle != this->handle) + { + AuWin32CloseHandle(this->writeHandle); + } + this->writeHandle = INVALID_HANDLE_VALUE; AuWin32CloseHandle(this->handle); } @@ -103,14 +108,16 @@ namespace Aurora::IO::FS this->directIO = directIO; this->handle = fileHandle; + this->writeHandle = fileHandle; this->readOnly = openMode == EFileOpenMode::eRead; return true; } - void FileHandle::Init(HANDLE h) + void FileHandle::Init(HANDLE read, HANDLE write) { this->directIO = true; - this->handle = h; + this->handle = read; + this->writeHandle = write; this->readOnly = false; } @@ -272,7 +279,7 @@ namespace Aurora::IO::FS this->overlap_.Offset = offset & 0xFFFFFFFF; this->overlap_.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; - auto ret = ::WriteFileEx(this->handle_->handle, memoryView->ptr, memoryView->length, &overlap_, GenericCompletionRoutine); + auto ret = ::WriteFileEx(this->handle_->writeHandle, memoryView->ptr, memoryView->length, &overlap_, GenericCompletionRoutine); return TranslateNtStatus(this, ret); } diff --git a/Source/IO/FS/Async.NT.hpp b/Source/IO/FS/Async.NT.hpp index 29a138f5..d5988d99 100644 --- a/Source/IO/FS/Async.NT.hpp +++ b/Source/IO/FS/Async.NT.hpp @@ -14,9 +14,9 @@ namespace Aurora::IO::FS ~FileHandle(); bool Init(const AuString &path, EFileOpenMode openMode, bool directIO, EFileAdvisoryLockLevel lock); - void Init(HANDLE h); + void Init(HANDLE read, HANDLE write); - HANDLE handle {INVALID_HANDLE_VALUE}; + HANDLE handle {INVALID_HANDLE_VALUE}, writeHandle {INVALID_HANDLE_VALUE}; AuString path; bool readOnly; bool directIO; diff --git a/Source/IPC/IPCPipe.NT.cpp b/Source/IPC/IPCPipe.NT.cpp index 7f976349..9838db3d 100644 --- a/Source/IPC/IPCPipe.NT.cpp +++ b/Source/IPC/IPCPipe.NT.cpp @@ -111,7 +111,7 @@ namespace Aurora::IPC this->fsHandle_ = AuMakeShared(); this->fsStream_ = AuMakeShared(); - this->fsHandle_->Init(this->GetPipeHandle()); + this->fsHandle_->Init(this->GetPipeHandle(), this->GetPipeHandle()); this->fsStream_->Init(this->fsHandle_); TryConnect(); diff --git a/Source/IPC/IPCPipe.Unix.cpp b/Source/IPC/IPCPipe.Unix.cpp index ff270461..44c60f8c 100755 --- a/Source/IPC/IPCPipe.Unix.cpp +++ b/Source/IPC/IPCPipe.Unix.cpp @@ -183,7 +183,7 @@ namespace Aurora::IPC bool IPCPipeImpl::Write(const Memory::MemoryViewStreamRead &read)//, bool nonblock) { - bool nonblock = false; + bool nonblock = true; auto handle = this->fds[1]; auto control = ::fcntl(handle, F_GETFL); auto ref = control; diff --git a/Source/Processes/Process.NT.cpp b/Source/Processes/Process.NT.cpp index 125766b7..e657ccd1 100644 --- a/Source/Processes/Process.NT.cpp +++ b/Source/Processes/Process.NT.cpp @@ -17,6 +17,7 @@ #include "ArgvQuote.hpp" #include +#include namespace Aurora::Processes { @@ -121,12 +122,17 @@ namespace Aurora::Processes void ProcessImpl::ShutdownPipes() { - AuWin32CloseHandle(this->pipeStdOutRead_); AuWin32CloseHandle(this->pipeStdOutWrite_); - AuWin32CloseHandle(this->pipeStdErrRead_); AuWin32CloseHandle(this->pipeStdErrWrite_); AuWin32CloseHandle(this->pipeStdInRead_); - AuWin32CloseHandle(this->pipeStdInWrite_); + //AuWin32CloseHandle(this->pipeStdOutRead_); + //AuWin32CloseHandle(this->pipeStdErrRead_); + //AuWin32CloseHandle(this->pipeStdInWrite_); + this->pipeStdInWrite_ = this->pipeStdOutRead_ = this->pipeStdErrRead_ = INVALID_HANDLE_VALUE; + this->fsHandle_.reset(); + this->fsStream_.reset(); + this->fsErrorHandle_.reset(); + this->fsErrorStream_.reset(); } bool ProcessImpl::Read(EStandardHandle stream, const AuMemoryViewStreamWrite &destination, bool nonblock) @@ -187,7 +193,7 @@ namespace Aurora::Processes return false; } - return WriteFile(pipeStdInWrite_, in.ptr, size, &size, NULL) && size == in.length; + return WriteFile(this->pipeStdInWrite_, in.ptr, size, &size, NULL) && size == in.length; } bool ProcessImpl::Init() @@ -276,9 +282,55 @@ namespace Aurora::Processes } } + if (this->startup_.fwdIn || this->startup_.fwdOut) + { + this->fsHandle_ = AuMakeShared(); + if (!this->fsHandle_) + { + return false; + } + + this->fsStream_ = AuMakeShared(); + if (!this->fsStream_) + { + return false; + } + + this->fsHandle_->Init(this->pipeStdOutRead_, this->pipeStdInWrite_); + this->fsStream_->Init(this->fsHandle_); + } + + if (this->startup_.fwdErr) + { + this->fsErrorHandle_ = AuMakeShared(); + if (!this->fsErrorHandle_) + { + return false; + } + + this->fsErrorStream_ = AuMakeShared(); + if (!this->fsErrorStream_) + { + return false; + } + + this->fsErrorHandle_->Init(this->pipeStdErrRead_, INVALID_HANDLE_VALUE); + this->fsErrorStream_->Init(this->fsErrorHandle_); + } + return true; } + AuSPtr ProcessImpl::NewAsyncTransaction() + { + return this->fsStream_ ? this->fsStream_->NewTransaction() : AuSPtr {}; + } + + AuSPtr ProcessImpl::NewErrorStreamAsyncTransaction() + { + return this->fsErrorStream_ ? this->fsErrorStream_->NewTransaction() : AuSPtr {}; + } + bool ProcessImpl::Start() { if (this->process_ != INVALID_HANDLE_VALUE) diff --git a/Source/Processes/Process.NT.hpp b/Source/Processes/Process.NT.hpp index aeba298e..aa3241af 100644 --- a/Source/Processes/Process.NT.hpp +++ b/Source/Processes/Process.NT.hpp @@ -7,6 +7,8 @@ ***/ #pragma once +#include + namespace Aurora::Processes { class ProcessImpl : public IProcess @@ -27,9 +29,12 @@ namespace Aurora::Processes AuSInt GetExitCode() override; void ShutdownPipes(); - + bool Read(EStandardHandle stream, const AuMemoryViewStreamWrite &destination, bool nonblock) override; bool Write(const AuMemoryViewStreamRead &source) override; + + AuSPtr NewAsyncTransaction() override; + AuSPtr NewErrorStreamAsyncTransaction() override; bool Start() override; @@ -43,7 +48,13 @@ namespace Aurora::Processes HANDLE pipeStdErrWrite_ {INVALID_HANDLE_VALUE}; HANDLE pipeStdInRead_ {INVALID_HANDLE_VALUE}; HANDLE pipeStdInWrite_ {INVALID_HANDLE_VALUE}; - + + AuSPtr fsHandle_; + AuSPtr fsStream_; + + AuSPtr fsErrorHandle_; + AuSPtr fsErrorStream_; + StartupParmaters startup_; ESpawnType type_;