diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/common/SubProcess.cpp | 51 | ||||
-rw-r--r-- | src/common/platform/unix/PosixSpawnSubProcess.cpp | 13 |
3 files changed, 65 insertions, 0 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index e6048d44..714a4636 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -22,6 +22,7 @@ target_compile_definitions(CruBase PUBLIC $<$<CONFIG:Debug>:CRU_DEBUG>) if (UNIX AND NOT EMSCRIPTEN) target_sources(CruBase PRIVATE platform/unix/UnixFileStream.cpp + platform/unix/UnixFileStream.cpp ) if (NOT APPLE) diff --git a/src/common/SubProcess.cpp b/src/common/SubProcess.cpp index 7b585e2f..f2bcf919 100644 --- a/src/common/SubProcess.cpp +++ b/src/common/SubProcess.cpp @@ -1,6 +1,57 @@ #include "cru/common/SubProcess.h" +#include "cru/common/Exception.h" + +#include <mutex> namespace cru { +SubProcessException::SubProcessException(String message) + : Exception(std::move(message)) {} + +SubProcessException::~SubProcessException() {} + +PlatformSubProcessBase::PlatformSubProcessBase( + const PlatformSubProcessStartInfo& start_info) + : dispose_(DisposeKind::None), + start_info_(start_info), + data_lock_(data_mutex_, std::defer_lock), + process_lock_(process_mutex_, std::defer_lock) {} + +PlatformSubProcessBase::~PlatformSubProcessBase() { + auto data_lock_guard = CreateDataLockGuard(); + if (status_ ) + switch (dispose_) { DisposeKind::Join: } +} + +void PlatformSubProcessBase::Start() { + auto data_lock_guard = CreateDataLockGuard(); + + if (status_ != PlatformSubProcessStatus::Prepare) { + throw SubProcessException(u"Sub-process has already run."); + } + + status_ = PlatformSubProcessStatus::Running; + + try { + PlatformCreateProcess(); + + process_thread_ = std::thread([this] { + auto process_lock_guard = CreateProcessLockGuard(); + PlatformWaitForProcess(); + auto data_lock_guard = CreateDataLockGuard(); + status_ = PlatformSubProcessStatus::Exited; + }); + } catch (const std::exception& e) { + status_ = PlatformSubProcessStatus::FailToStart; + } +} +void PlatformSubProcessBase::Wait( + std::optional<std::chrono::milliseconds> wait_time) { + if (wait_time) { + process_lock_.try_lock_for(*wait_time); + } else { + process_lock_.lock(); + } } +} // namespace cru diff --git a/src/common/platform/unix/PosixSpawnSubProcess.cpp b/src/common/platform/unix/PosixSpawnSubProcess.cpp new file mode 100644 index 00000000..6a8a8d0f --- /dev/null +++ b/src/common/platform/unix/PosixSpawnSubProcess.cpp @@ -0,0 +1,13 @@ +#include "cru/common/platform/unix/PosixSpawnSubProcess.h" +#include "cru/common/SubProcess.h" + +#include <spawn.h> + +namespace cru::platform::unix { +PosixSpawnSubProcess::PosixSpawnSubProcess( + const PlatformSubProcessStartInfo& start_info) + : PlatformSubProcessBase(start_info), pid_(0), exit_code_(0) {} + +PosixSpawnSubProcess::~PosixSpawnSubProcess() {} + +} // namespace cru::platform::unix |