diff options
author | crupest <crupest@outlook.com> | 2024-06-01 17:09:44 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2024-06-08 23:18:04 +0800 |
commit | 4725b4bc48722356fea4570ed7770137a0999491 (patch) | |
tree | 4d2ca789e2205496f2c64f3b50a371ed131c0074 /src/common/SubProcess.cpp | |
parent | b165ebcfb9c278dc7481abb5287e85672731c005 (diff) | |
download | cru-4725b4bc48722356fea4570ed7770137a0999491.tar.gz cru-4725b4bc48722356fea4570ed7770137a0999491.tar.bz2 cru-4725b4bc48722356fea4570ed7770137a0999491.zip |
HALF WORK: develop SubProcess.
Diffstat (limited to 'src/common/SubProcess.cpp')
-rw-r--r-- | src/common/SubProcess.cpp | 88 |
1 files changed, 84 insertions, 4 deletions
diff --git a/src/common/SubProcess.cpp b/src/common/SubProcess.cpp index ae1c5375..fbe15859 100644 --- a/src/common/SubProcess.cpp +++ b/src/common/SubProcess.cpp @@ -1,14 +1,28 @@ #include "cru/common/SubProcess.h" +#include <exception> #include "cru/common/Exception.h" +#include "cru/common/log/Logger.h" + +#ifdef CRU_PLATFORM_UNIX +#include "cru/common/platform/unix/PosixSpawnSubProcess.h" +#endif #include <mutex> namespace cru { -PlatformSubProcessBase::PlatformSubProcessBase( - const SubProcessStartInfo& start_info) - : start_info_(start_info), process_lock_(process_mutex_, std::defer_lock) {} +PlatformSubProcessBase::PlatformSubProcessBase(SubProcessStartInfo start_info) + : start_info_(std::move(start_info)), + delete_self_(false), + process_lock_(process_mutex_, std::defer_lock) {} -PlatformSubProcessBase::~PlatformSubProcessBase() {} +PlatformSubProcessBase::~PlatformSubProcessBase() { + std::lock_guard lock_guard(process_lock_); + if (status_ == SubProcessStatus::Running) { + CRU_LOG_ERROR( + u"PlatformSubProcessBase is destroyed but process is still running."); + std::terminate(); + } +} void PlatformSubProcessBase::Start() { std::lock_guard lock_guard(process_lock_); @@ -30,6 +44,9 @@ void PlatformSubProcessBase::Start() { status_ = SubProcessStatus::Exited; } this->process_condition_variable_.notify_all(); + if (this->delete_self_) { + delete this; + } }); process_thread_.detach(); @@ -110,4 +127,67 @@ SubProcessExitResult PlatformSubProcessBase::GetExitResult() { return exit_result_; } + +void PlatformSubProcessBase::SetDeleteSelfOnExit(bool enable) { + std::lock_guard lock_guard(process_lock_); + delete_self_ = enable; +} + +#ifdef CRU_PLATFORM_UNIX +using PlatformSubProcess = platform::unix::PosixSpawnSubProcess; +#endif + +SubProcess::SubProcess(SubProcessStartInfo start_info) { + platform_process_.reset(new PlatformSubProcess(std::move(start_info))); + platform_process_->Start(); +} + +SubProcess::~SubProcess() {} + +void SubProcess::Wait(std::optional<std::chrono::milliseconds> wait_time) { + CheckValid(); + platform_process_->Wait(wait_time); +} + +void SubProcess::Kill() { + CheckValid(); + platform_process_->Kill(); +} + +SubProcessStatus SubProcess::GetStatus() { + CheckValid(); + return platform_process_->GetStatus(); +} + +SubProcessExitResult SubProcess::GetExitResult() { + CheckValid(); + return platform_process_->GetExitResult(); +} + +io::Stream* SubProcess::GetStdinStream() { + CheckValid(); + return platform_process_->GetStdinStream(); +} + +io::Stream* SubProcess::GetStdoutStream() { + CheckValid(); + return platform_process_->GetStdoutStream(); +} + +io::Stream* SubProcess::GetStderrStream() { + CheckValid(); + return platform_process_->GetStderrStream(); +} + +void SubProcess::Detach() { + auto p = platform_process_.release(); + p->SetDeleteSelfOnExit(true); +} + +void SubProcess::CheckValid() const { + if (!IsValid()) { + throw SubProcessException(u"SubProcess instance is invalid."); + } +} + } // namespace cru |