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; static boost::once_flag l_SpawnHelperOnceFlag = BOOST_ONCE_INIT;
Process::Process(Process::Arguments arguments, Dictionary::Ptr extraEnvironment) 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 #ifdef _WIN32
, m_ReadPending(false), m_ReadFailed(false), m_Overlapped() , m_ReadPending(false), m_ReadFailed(false), m_Overlapped()
#endif /* _WIN32 */ #endif /* _WIN32 */
@ -1014,6 +1015,12 @@ void Process::Run(const std::function<void(const ProcessResult&)>& callback)
#endif /* _WIN32 */ #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 Process::DoEvents()
{ {
bool is_timeout = false; bool is_timeout = false;
@ -1121,10 +1128,15 @@ bool Process::DoEvents()
} }
#endif /* _WIN32 */ #endif /* _WIN32 */
m_Result.PID = m_PID; {
m_Result.ExecutionEnd = Utility::GetTime(); std::lock_guard<std::mutex> lock(m_ResultMutex);
m_Result.ExitStatus = exitcode; m_Result.PID = m_PID;
m_Result.Output = output; m_Result.ExecutionEnd = Utility::GetTime();
m_Result.ExitStatus = exitcode;
m_Result.Output = output;
m_ResultAvailable = true;
}
m_ResultCondition.notify_all();
if (m_Callback) if (m_Callback)
Utility::QueueAsyncCallback(std::bind(m_Callback, m_Result)); Utility::QueueAsyncCallback(std::bind(m_Callback, m_Result));

View File

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