diff --git a/stepmania/src/RageUtil_WorkerThread.cpp b/stepmania/src/RageUtil_WorkerThread.cpp index e3f39b527f..63de7052e0 100644 --- a/stepmania/src/RageUtil_WorkerThread.cpp +++ b/stepmania/src/RageUtil_WorkerThread.cpp @@ -3,7 +3,8 @@ #include "RageLog.h" WorkerThread::WorkerThread( const CString &sName ): - m_WorkerEvent( "\"" + sName + "\" worker event" ) + m_WorkerEvent( "\"" + sName + "\" worker event" ), + m_HeartbeatEvent( "\"" + sName + "\" heartbeat event" ) { m_Timeout.SetZero(); m_iRequest = REQ_NONE; @@ -122,6 +123,12 @@ void WorkerThread::WorkerMain() { DoHeartbeat(); + /* Wake up anyone waiting for a heartbeat. */ + m_HeartbeatEvent.Lock(); + m_HeartbeatEvent.Broadcast(); + m_HeartbeatEvent.Unlock(); + + /* Schedule the next heartbeat. */ m_NextHeartbeat.Touch(); m_NextHeartbeat += m_fHeartbeat; } @@ -164,6 +171,18 @@ void WorkerThread::WorkerMain() } } +bool WorkerThread::WaitForOneHeartbeat() +{ + /* It doesn't make sense to wait for a heartbeat if there is no heartbeat. */ + ASSERT( m_fHeartbeat != -1 ); + + m_HeartbeatEvent.Lock(); + bool bTimedOut = !m_HeartbeatEvent.Wait( &m_Timeout ); + m_HeartbeatEvent.Unlock(); + + return !bTimedOut; +} + /* * (c) 2005 Glenn Maynard * All rights reserved. diff --git a/stepmania/src/RageUtil_WorkerThread.h b/stepmania/src/RageUtil_WorkerThread.h index 6c4722579d..509e4d69bb 100644 --- a/stepmania/src/RageUtil_WorkerThread.h +++ b/stepmania/src/RageUtil_WorkerThread.h @@ -18,6 +18,13 @@ public: void SetTimeout( float fSeconds ); bool TimeoutEnabled() const { return !m_Timeout.IsZero(); } + /* Return true if the last operation has timed out and has not yet recovered. */ + bool IsTimedOut() const { return m_bTimedOut; } + + /* Pause until the next heartbeat completes. Returns false if timed out. This + * triggers no actions, so no cleanup is run and IsTimedOut() is not affected. */ + bool WaitForOneHeartbeat(); + protected: /* Call this in the derived class to start and stop the thread. */ void StartThread(); @@ -28,9 +35,6 @@ protected: * timed out and DoRequest() must not be called. */ bool DoRequest( int iRequest ); - /* Return true if the last operation has timed out and has not yet recovered. */ - bool IsTimedOut() const { return m_bTimedOut; } - /* Overload this in the derived class to handle requests. */ virtual void HandleRequest( int iRequest ) = 0; @@ -58,6 +62,7 @@ private: float m_fHeartbeat; RageTimer m_NextHeartbeat; + RageEvent m_HeartbeatEvent; }; #endif