diff options
author | crupest <crupest@outlook.com> | 2024-06-24 00:06:25 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2024-07-21 22:33:50 +0800 |
commit | 1e8bb0de0b0b05dc1323520dfa57df1f19b51b83 (patch) | |
tree | 225bfbf13ecf1a97e2573c174ee867f7301186be /src/common | |
parent | 5f0d7dc36a7a0091bfc152be9f06730cd08eb4dd (diff) | |
download | cru-1e8bb0de0b0b05dc1323520dfa57df1f19b51b83.tar.gz cru-1e8bb0de0b0b05dc1323520dfa57df1f19b51b83.tar.bz2 cru-1e8bb0de0b0b05dc1323520dfa57df1f19b51b83.zip |
fix: a lock bug and add test for Wait.
NEED TEST: BufferStream, AutoReadStream, SubProcess.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/SubProcess.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/common/SubProcess.cpp b/src/common/SubProcess.cpp index 0ffb2387..33926f39 100644 --- a/src/common/SubProcess.cpp +++ b/src/common/SubProcess.cpp @@ -15,12 +15,13 @@ using ThisPlatformSubProcessImpl = platform::unix::PosixSpawnSubProcessImpl; PlatformSubProcess::PlatformSubProcess( SubProcessStartInfo start_info, std::shared_ptr<IPlatformSubProcessImpl> impl) - : state_(new State(std::move(start_info), std::move(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->state_->lock); + std::lock_guard lock_guard(this->lock_); if (this->state_->status != SubProcessStatus::Prepare) { throw SubProcessException(u"The process has already tried to start."); @@ -31,7 +32,7 @@ void PlatformSubProcess::Start() { this->state_->status = SubProcessStatus::Running; auto thread = std::thread([state = state_] { - std::lock_guard lock_guard(state->lock); + std::unique_lock lock(state->mutex); state->exit_result = state->impl->PlatformWaitForProcess(); state->status = SubProcessStatus::Exited; state->condition_variable.notify_all(); @@ -47,7 +48,7 @@ void PlatformSubProcess::Start() { void PlatformSubProcess::Wait( std::optional<std::chrono::milliseconds> wait_time) { - std::lock_guard lock_guard(this->state_->lock); + std::lock_guard lock_guard(this->lock_); if (this->state_->status == SubProcessStatus::Prepare) { throw SubProcessException( @@ -68,15 +69,15 @@ void PlatformSubProcess::Wait( }; if (wait_time) { - this->state_->condition_variable.wait_for(this->state_->lock, *wait_time, + this->state_->condition_variable.wait_for(this->lock_, *wait_time, predicate); } else { - this->state_->condition_variable.wait(this->state_->lock, predicate); + this->state_->condition_variable.wait(this->lock_, predicate); } } void PlatformSubProcess::Kill() { - std::lock_guard lock_guard(this->state_->lock); + 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."); @@ -99,12 +100,12 @@ void PlatformSubProcess::Kill() { } SubProcessStatus PlatformSubProcess::GetStatus() { - std::lock_guard lock_guard(this->state_->lock); + std::lock_guard lock_guard(this->lock_); return this->state_->status; } SubProcessExitResult PlatformSubProcess::GetExitResult() { - std::lock_guard lock_guard(this->state_->lock); + std::lock_guard lock_guard(this->lock_); if (this->state_->status == SubProcessStatus::Prepare) { throw SubProcessException( @@ -145,6 +146,15 @@ SubProcess SubProcess::Create(String program, std::vector<String> arguments, 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>())); |