Add Process::WaitForResult to allow waiting for the process to finish

This commit is contained in:
Julian Brost 2020-11-16 17:10:26 +01:00
parent 2d5e244127
commit 4c8c4c75ec
2 changed files with 24 additions and 5 deletions

View File

@ -49,7 +49,8 @@ static boost::once_flag l_ProcessOnceFlag = BOOST_ONCE_INIT;
static boost::once_flag l_SpawnHelperOnceFlag = BOOST_ONCE_INIT;
Process::Process(Process::Arguments arguments, Dictionary::Ptr extraEnvironment)
: m_Arguments(std::move(arguments)), m_ExtraEnvironment(std::move(extraEnvironment)), m_Timeout(600), m_AdjustPriority(false)
: m_Arguments(std::move(arguments)), m_ExtraEnvironment(std::move(extraEnvironment)),
m_Timeout(600), m_AdjustPriority(false), m_ResultAvailable(false)
#ifdef _WIN32
, m_ReadPending(false), m_ReadFailed(false), m_Overlapped()
#endif /* _WIN32 */
@ -1014,6 +1015,12 @@ void Process::Run(const std::function<void(const ProcessResult&)>& callback)
#endif /* _WIN32 */
}
const ProcessResult& Process::WaitForResult() {
std::unique_lock<std::mutex> lock(m_ResultMutex);
m_ResultCondition.wait(lock, [this]{ return m_ResultAvailable; });
return m_Result;
}
bool Process::DoEvents()
{
bool is_timeout = false;
@ -1121,10 +1128,15 @@ bool Process::DoEvents()
}
#endif /* _WIN32 */
{
std::lock_guard<std::mutex> lock(m_ResultMutex);
m_Result.PID = m_PID;
m_Result.ExecutionEnd = Utility::GetTime();
m_Result.ExitStatus = exitcode;
m_Result.Output = output;
m_ResultAvailable = true;
}
m_ResultCondition.notify_all();
if (m_Callback)
Utility::QueueAsyncCallback(std::bind(m_Callback, m_Result));

View File

@ -9,6 +9,8 @@
#include <deque>
#include <vector>
#include <sstream>
#include <mutex>
#include <condition_variable>
namespace icinga
{
@ -61,6 +63,8 @@ public:
void Run(const std::function<void (const ProcessResult&)>& callback = std::function<void (const ProcessResult&)>());
const ProcessResult& WaitForResult();
pid_t GetPID() const;
static Arguments PrepareCommand(const Value& command);
@ -94,6 +98,9 @@ private:
std::ostringstream m_OutputStream;
std::function<void (const ProcessResult&)> m_Callback;
ProcessResult m_Result;
bool m_ResultAvailable;
std::mutex m_ResultMutex;
std::condition_variable m_ResultCondition;
static void IOThreadProc(int tid);
bool DoEvents();