aboutsummaryrefslogtreecommitdiff
path: root/src/common/SubProcess.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2024-10-06 13:57:39 +0800
committercrupest <crupest@outlook.com>2024-10-06 13:57:39 +0800
commitdfe62dcf8bcefc523b466e127c3edc4dc2756629 (patch)
tree1c751a14ba0da07ca2ff805633f97568060aa4c9 /src/common/SubProcess.cpp
parentf51eb955e188858272230a990565931e7403f23b (diff)
downloadcru-dfe62dcf8bcefc523b466e127c3edc4dc2756629.tar.gz
cru-dfe62dcf8bcefc523b466e127c3edc4dc2756629.tar.bz2
cru-dfe62dcf8bcefc523b466e127c3edc4dc2756629.zip
Rename common to base.
Diffstat (limited to 'src/common/SubProcess.cpp')
-rw-r--r--src/common/SubProcess.cpp209
1 files changed, 0 insertions, 209 deletions
diff --git a/src/common/SubProcess.cpp b/src/common/SubProcess.cpp
deleted file mode 100644
index 33926f39..00000000
--- a/src/common/SubProcess.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-#include "cru/common/SubProcess.h"
-
-#include <thread>
-
-#ifdef CRU_PLATFORM_UNIX
-#include "cru/common/platform/unix/PosixSpawnSubProcess.h"
-#endif
-
-namespace cru {
-
-#ifdef CRU_PLATFORM_UNIX
-using ThisPlatformSubProcessImpl = platform::unix::PosixSpawnSubProcessImpl;
-#endif
-
-PlatformSubProcess::PlatformSubProcess(
- SubProcessStartInfo start_info,
- std::shared_ptr<IPlatformSubProcessImpl> impl)
- : state_(new State(std::move(start_info), std::move(impl))),
- lock_(state_->mutex, std::defer_lock) {}
-
-PlatformSubProcess::~PlatformSubProcess() {}
-
-void PlatformSubProcess::Start() {
- std::lock_guard lock_guard(this->lock_);
-
- if (this->state_->status != SubProcessStatus::Prepare) {
- throw SubProcessException(u"The process has already tried to start.");
- }
-
- try {
- this->state_->impl->PlatformCreateProcess(this->state_->start_info);
- this->state_->status = SubProcessStatus::Running;
-
- auto thread = std::thread([state = state_] {
- std::unique_lock lock(state->mutex);
- state->exit_result = state->impl->PlatformWaitForProcess();
- state->status = SubProcessStatus::Exited;
- state->condition_variable.notify_all();
- });
-
- thread.detach();
- } catch (const std::exception& e) {
- this->state_->status = SubProcessStatus::FailedToStart;
- throw SubProcessFailedToStartException(u"Sub-process failed to start. " +
- String::FromUtf8(e.what()));
- }
-}
-
-void PlatformSubProcess::Wait(
- std::optional<std::chrono::milliseconds> wait_time) {
- std::lock_guard lock_guard(this->lock_);
-
- if (this->state_->status == SubProcessStatus::Prepare) {
- throw SubProcessException(
- u"The process does not start. Can't wait for it.");
- }
-
- if (this->state_->status == SubProcessStatus::FailedToStart) {
- throw SubProcessException(
- u"The process failed to start. Can't wait for it.");
- }
-
- if (this->state_->status == SubProcessStatus::Exited) {
- return;
- }
-
- auto predicate = [this] {
- return this->state_->status == SubProcessStatus::Exited;
- };
-
- if (wait_time) {
- this->state_->condition_variable.wait_for(this->lock_, *wait_time,
- predicate);
- } else {
- this->state_->condition_variable.wait(this->lock_, predicate);
- }
-}
-
-void PlatformSubProcess::Kill() {
- std::lock_guard lock_guard(this->lock_);
-
- if (this->state_->status == SubProcessStatus::Prepare) {
- throw SubProcessException(u"The process does not start. Can't kill it.");
- }
-
- if (this->state_->status == SubProcessStatus::FailedToStart) {
- throw SubProcessException(u"The process failed to start. Can't kill it.");
- }
-
- if (this->state_->status == SubProcessStatus::Exited) {
- return;
- }
-
- if (this->state_->killed) {
- return;
- }
-
- this->state_->impl->PlatformKillProcess();
- this->state_->killed = true;
-}
-
-SubProcessStatus PlatformSubProcess::GetStatus() {
- std::lock_guard lock_guard(this->lock_);
- return this->state_->status;
-}
-
-SubProcessExitResult PlatformSubProcess::GetExitResult() {
- std::lock_guard lock_guard(this->lock_);
-
- if (this->state_->status == SubProcessStatus::Prepare) {
- throw SubProcessException(
- u"The process does not start. Can't get exit result.");
- }
-
- if (this->state_->status == SubProcessStatus::FailedToStart) {
- throw SubProcessException(
- u"The process failed to start. Can't get exit result.");
- }
-
- if (this->state_->status == SubProcessStatus::Running) {
- throw SubProcessException(
- u"The process is running. Can't get exit result.");
- }
-
- return this->state_->exit_result;
-}
-
-io::Stream* PlatformSubProcess::GetStdinStream() {
- return this->state_->impl->GetStdinStream();
-}
-
-io::Stream* PlatformSubProcess::GetStdoutStream() {
- return this->state_->impl->GetStdoutStream();
-}
-
-io::Stream* PlatformSubProcess::GetStderrStream() {
- return this->state_->impl->GetStderrStream();
-}
-
-SubProcess SubProcess::Create(String program, std::vector<String> arguments,
- std::unordered_map<String, String> environments) {
- SubProcessStartInfo start_info;
- start_info.program = std::move(program);
- start_info.arguments = std::move(arguments);
- start_info.environments = std::move(environments);
- return SubProcess(std::move(start_info));
-}
-
-SubProcessExitResult SubProcess::Call(
- String program, std::vector<String> arguments,
- std::unordered_map<String, String> environments) {
- auto process =
- Create(std::move(program), std::move(arguments), std::move(environments));
- process.Wait();
- return process.GetExitResult();
-}
-
-SubProcess::SubProcess(SubProcessStartInfo start_info) {
- platform_process_.reset(new PlatformSubProcess(
- std::move(start_info), std::make_shared<ThisPlatformSubProcessImpl>()));
- 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(); }
-
-void SubProcess::CheckValid() const {
- if (!IsValid()) {
- throw SubProcessException(u"SubProcess instance is invalid.");
- }
-}
-
-} // namespace cru