From 4b1b3edc21acf3b19649a85e49a57464bf169314 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Thu, 16 Sep 2021 21:04:35 +0200 Subject: Added ProcessMonitor class, which is used to monitor a number of sponsor processes, to control Zen instance lifetime --- zencore/thread.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'zencore/thread.cpp') diff --git a/zencore/thread.cpp b/zencore/thread.cpp index 598466bb4..ee00d38d4 100644 --- a/zencore/thread.cpp +++ b/zencore/thread.cpp @@ -76,6 +76,13 @@ Event::Reset() ResetEvent(m_EventHandle); } +void +Event::Close() +{ + CloseHandle(m_EventHandle); + m_EventHandle = nullptr; +} + bool Event::Wait(int TimeoutMs) { @@ -168,6 +175,7 @@ ProcessHandle::Initialize(void* ProcessHandle) ZEN_ASSERT(m_ProcessHandle == nullptr); // TODO: perform some debug verification here to verify it's a valid handle? m_ProcessHandle = ProcessHandle; + m_Pid = GetProcessId(m_ProcessHandle); } ProcessHandle::~ProcessHandle() @@ -255,6 +263,73 @@ ProcessHandle::Wait(int TimeoutMs) return false; } +////////////////////////////////////////////////////////////////////////// + +ProcessMonitor::ProcessMonitor() +{ +} + +ProcessMonitor::~ProcessMonitor() +{ + RwLock::ExclusiveLockScope _(m_Lock); + + for (HANDLE& Proc : m_ProcessHandles) + { + CloseHandle(Proc); + Proc = 0; + } +} + +bool +ProcessMonitor::IsRunning() +{ + RwLock::ExclusiveLockScope _(m_Lock); + + bool FoundOne = false; + + for (HANDLE& Proc : m_ProcessHandles) + { + DWORD ExitCode = 0; + GetExitCodeProcess(Proc, &ExitCode); + + if (ExitCode != STILL_ACTIVE) + { + CloseHandle(Proc); + Proc = 0; + } + else + { + // Still alive + FoundOne = true; + } + } + + std::erase_if(m_ProcessHandles, [](HANDLE Handle) { return Handle == 0; }); + + return FoundOne; +} + +void +ProcessMonitor::AddPid(int Pid) +{ + HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, Pid); + + if (ProcessHandle) + { + RwLock::ExclusiveLockScope _(m_Lock); + m_ProcessHandles.push_back(ProcessHandle); + } +} + +bool +ProcessMonitor::IsActive() const +{ + RwLock::SharedLockScope _(m_Lock); + return m_ProcessHandles.empty() == false; +} + +////////////////////////////////////////////////////////////////////////// + bool IsProcessRunning(int pid) { -- cgit v1.2.3