aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/SubProcess.cpp51
-rw-r--r--src/common/platform/unix/PosixSpawnSubProcess.cpp13
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