aboutsummaryrefslogtreecommitdiff
path: root/src/common/SubProcess.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/SubProcess.cpp')
-rw-r--r--src/common/SubProcess.cpp136
1 files changed, 3 insertions, 133 deletions
diff --git a/src/common/SubProcess.cpp b/src/common/SubProcess.cpp
index e2738248..69f52d9c 100644
--- a/src/common/SubProcess.cpp
+++ b/src/common/SubProcess.cpp
@@ -1,140 +1,13 @@
#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(SubProcessStartInfo start_info)
- : start_info_(std::move(start_info)),
- delete_self_(false),
- process_lock_(process_mutex_, std::defer_lock) {}
-
-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_);
-
- if (status_ != SubProcessStatus::Prepare) {
- throw SubProcessException(u"The process has already tried to start.");
- }
-
- try {
- PlatformCreateProcess();
-
- status_ = SubProcessStatus::Running;
-
- process_thread_ = std::thread([this] {
- auto exit_result = PlatformWaitForProcess();
- {
- std::lock_guard lock_guard(process_lock_);
- exit_result_ = std::move(exit_result);
- status_ = SubProcessStatus::Exited;
- }
- this->process_condition_variable_.notify_all();
- if (this->delete_self_) {
- delete this;
- }
- });
-
- process_thread_.detach();
- } catch (const std::exception& e) {
- status_ = SubProcessStatus::FailedToStart;
- throw SubProcessFailedToStartException(u"Sub-process failed to start. " +
- String::FromUtf8(e.what()));
- }
-}
-
-void PlatformSubProcessBase::Wait(
- std::optional<std::chrono::milliseconds> wait_time) {
- std::lock_guard lock_guard(process_lock_);
-
- if (status_ == SubProcessStatus::Prepare) {
- throw SubProcessException(
- u"The process does not start. Can't wait for it.");
- }
-
- if (status_ == SubProcessStatus::FailedToStart) {
- throw SubProcessException(
- u"The process failed to start. Can't wait for it.");
- }
-
- if (status_ == SubProcessStatus::Exited) {
- return;
- }
-
- auto predicate = [this] { return status_ == SubProcessStatus::Exited; };
-
- if (wait_time) {
- process_condition_variable_.wait_for(process_lock_, *wait_time, predicate);
- } else {
- process_condition_variable_.wait(process_lock_, predicate);
- }
-}
-
-void PlatformSubProcessBase::Kill() {
- std::lock_guard data_lock_guard(process_lock_);
-
- if (status_ == SubProcessStatus::Prepare) {
- throw SubProcessException(u"The process does not start. Can't kill it.");
- }
-
- if (status_ == SubProcessStatus::FailedToStart) {
- throw SubProcessException(u"The process failed to start. Can't kill it.");
- }
-
- if (status_ == SubProcessStatus::Exited) {
- return;
- }
-
- PlatformKillProcess();
-}
-
-SubProcessStatus PlatformSubProcessBase::GetStatus() {
- std::lock_guard data_lock_guard(process_lock_);
- return status_;
-}
-
-SubProcessExitResult PlatformSubProcessBase::GetExitResult() {
- std::lock_guard lock_guard(process_lock_);
-
- if (status_ == SubProcessStatus::Prepare) {
- throw SubProcessException(
- u"The process does not start. Can't get exit result.");
- }
-
- if (status_ == SubProcessStatus::FailedToStart) {
- throw SubProcessException(
- u"The process failed to start. Can't get exit result.");
- }
-
- if (status_ == SubProcessStatus::Running) {
- throw SubProcessException(
- u"The process is running. Can't get exit result.");
- }
-
- 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;
+using ThisPlatformSubProcess = platform::unix::PosixSpawnSubProcess;
#endif
SubProcess SubProcess::Create(String program, std::vector<String> arguments,
@@ -147,7 +20,7 @@ SubProcess SubProcess::Create(String program, std::vector<String> arguments,
}
SubProcess::SubProcess(SubProcessStartInfo start_info) {
- platform_process_.reset(new PlatformSubProcess(std::move(start_info)));
+ platform_process_.reset(new ThisPlatformSubProcess(std::move(start_info)));
platform_process_->Start();
}
@@ -188,10 +61,7 @@ io::Stream* SubProcess::GetStderrStream() {
return platform_process_->GetStderrStream();
}
-void SubProcess::Detach() {
- auto p = platform_process_.release();
- p->SetDeleteSelfOnExit(true);
-}
+void SubProcess::Detach() { auto p = platform_process_.release(); }
void SubProcess::CheckValid() const {
if (!IsValid()) {