metaforce/Runtime/CInfiniteLoopDetector.cpp

38 lines
1.4 KiB
C++

#include "Runtime/CInfiniteLoopDetector.hpp"
#include <logvisor/logvisor.hpp>
namespace metaforce {
namespace {
logvisor::Module Log("CInfiniteLoopDetector");
std::chrono::system_clock::time_point g_WatchDog = std::chrono::system_clock::now();
std::mutex g_mutex;
} // namespace
CInfiniteLoopDetector::CInfiniteLoopDetector(int duration)
: m_duration(duration), m_futureObj(m_stopRequested.get_future()) {}
bool CInfiniteLoopDetector::stopRequested() const {
return m_futureObj.wait_for(std::chrono::milliseconds(0)) != std::future_status::timeout;
}
void CInfiniteLoopDetector::run() {
std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
while (!stopRequested()) {
if (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start) >
std::chrono::milliseconds(m_duration)) {
std::lock_guard<std::mutex> guard(g_mutex);
if (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - g_WatchDog) >
std::chrono::milliseconds(m_duration)) {
Log.report(logvisor::Fatal, FMT_STRING("INFINITE LOOP DETECTED!"));
}
}
}
}
void CInfiniteLoopDetector::UpdateWatchDog(std::chrono::system_clock::time_point time) {
std::lock_guard<std::mutex> guard(g_mutex);
g_WatchDog = time;
}
void CInfiniteLoopDetector::stop() { m_stopRequested.set_value(); }
} // namespace metaforce