#include "Runtime/CInfiniteLoopDetector.hpp" #include 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::system_clock::now() - start) > std::chrono::milliseconds(m_duration)) { std::lock_guard guard(g_mutex); if (std::chrono::duration_cast(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 guard(g_mutex); g_WatchDog = time; } void CInfiniteLoopDetector::stop() { m_stopRequested.set_value(); } } // namespace metaforce