From 63604a65367154d8c5743d0195e511ef87b9cfc8 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 26 Jan 2005 20:59:41 +0000 Subject: [PATCH] implement RageEvent::Wait timeouts --- stepmania/src/RageThreads.cpp | 8 ++++++-- stepmania/src/RageThreads.h | 9 ++++++++- stepmania/src/arch/Threads/Threads.h | 4 ++-- stepmania/src/arch/Threads/Threads_Pthreads.cpp | 14 ++++++++++++-- stepmania/src/arch/Threads/Threads_Pthreads.h | 2 +- stepmania/src/arch/Threads/Threads_Win32.cpp | 7 +++++-- stepmania/src/arch/Threads/Threads_Win32.h | 2 +- 7 files changed, 35 insertions(+), 11 deletions(-) diff --git a/stepmania/src/RageThreads.cpp b/stepmania/src/RageThreads.cpp index 29aed19eeb..8c9ba15c0f 100644 --- a/stepmania/src/RageThreads.cpp +++ b/stepmania/src/RageThreads.cpp @@ -666,14 +666,18 @@ RageEvent::~RageEvent() } /* For each of these calls, the mutex must be locked, and must not be locked recursively. */ -void RageEvent::Wait() +bool RageEvent::Wait( RageTimer *pTimeout ) { ASSERT( IsLockedByThisThread() ); ASSERT( m_LockCnt == 0 ); - m_pEvent->Wait(); + /* A zero RageTimer also means no timeout. */ + if( pTimeout != NULL && pTimeout->IsZero() ) + pTimeout = NULL; + bool bRet = m_pEvent->Wait( pTimeout ); m_LockedBy = GetThisThreadId(); + return bRet; } void RageEvent::Signal() diff --git a/stepmania/src/RageThreads.h b/stepmania/src/RageThreads.h index fb0b7588f5..4595009b8b 100644 --- a/stepmania/src/RageThreads.h +++ b/stepmania/src/RageThreads.h @@ -2,6 +2,7 @@ #define RAGE_THREADS_H struct ThreadSlot; +class RageTimer; class RageThread { ThreadSlot *m_pSlot; @@ -137,7 +138,13 @@ public: RageEvent( CString name ); ~RageEvent(); - void Wait(); + /* + * If pTimeout is non-NULL, the event will be automatically signalled at the given + * time. Note that implementing this timeout is optional; not all archs support it. + * If false is returned, the wait timed out (and the mutex is locked, as if the + * event had been signalled). + */ + bool Wait( RageTimer *pTimeout = NULL ); void Signal(); void Broadcast(); diff --git a/stepmania/src/arch/Threads/Threads.h b/stepmania/src/arch/Threads/Threads.h index 8a3b566676..6759382b25 100644 --- a/stepmania/src/arch/Threads/Threads.h +++ b/stepmania/src/arch/Threads/Threads.h @@ -3,7 +3,7 @@ /* This is the low-level implementation; you probably want RageThreads. */ class RageMutex; - +class RageTimer; class ThreadImpl { @@ -46,7 +46,7 @@ class EventImpl { public: virtual ~EventImpl() { } - virtual void Wait() = 0; + virtual bool Wait( RageTimer *pTimeout ) = 0; virtual void Signal() = 0; virtual void Broadcast() = 0; }; diff --git a/stepmania/src/arch/Threads/Threads_Pthreads.cpp b/stepmania/src/arch/Threads/Threads_Pthreads.cpp index 2d627821fe..867d8e4051 100644 --- a/stepmania/src/arch/Threads/Threads_Pthreads.cpp +++ b/stepmania/src/arch/Threads/Threads_Pthreads.cpp @@ -215,9 +215,19 @@ EventImpl_Pthreads::~EventImpl_Pthreads() pthread_cond_destroy( &m_Cond ); } -void EventImpl_Pthreads::Wait() +bool EventImpl_Pthreads::Wait( RageTimer *pTimeout ) { - pthread_cond_wait( &m_Cond, &m_pParent->mutex ); + if( pTimeout == NULL ) + { + pthread_cond_wait( &m_Cond, &m_pParent->mutex ); + return true; + } + + timespec abstime; + timeout.tv_sec = pTimeout->m_secs; + timeout.tv_nsec = pTimeout->m_us * 1000; + int iRet = pthread_cond_timedwait( &m_Cond, &m_pParent->mutex ); + return iRet != ETIMEDOUT; } void EventImpl_Pthreads::Signal() diff --git a/stepmania/src/arch/Threads/Threads_Pthreads.h b/stepmania/src/arch/Threads/Threads_Pthreads.h index 3983fcd9ab..ee1415f4af 100644 --- a/stepmania/src/arch/Threads/Threads_Pthreads.h +++ b/stepmania/src/arch/Threads/Threads_Pthreads.h @@ -52,7 +52,7 @@ public: EventImpl_Pthreads( MutexImpl_Pthreads *pParent ); ~EventImpl_Pthreads(); - void Wait(); + bool Wait( RageTimer *pTimeout ); void Signal(); void Broadcast(); diff --git a/stepmania/src/arch/Threads/Threads_Win32.cpp b/stepmania/src/arch/Threads/Threads_Win32.cpp index d6f130d1ee..4de6776f7b 100644 --- a/stepmania/src/arch/Threads/Threads_Win32.cpp +++ b/stepmania/src/arch/Threads/Threads_Win32.cpp @@ -321,8 +321,9 @@ static void PortableSignalObjectAndWait( HANDLE hObjectToSignal, HANDLE hObjectT WaitForSingleObject( hObjectToWaitOn, INFINITE ); } -/* Event logic from http://www.cs.wustl.edu/~schmidt/win32-cv-1.html. */ -void EventImpl_Win32::Wait() +/* Event logic from http://www.cs.wustl.edu/~schmidt/win32-cv-1.html. + * pTimeout is not currently implemented. */ +bool EventImpl_Win32::Wait( RageTimer *pTimeout ) { EnterCriticalSection( &m_iNumWaitingLock ); ++m_iNumWaiting; @@ -342,6 +343,8 @@ void EventImpl_Win32::Wait() PortableSignalObjectAndWait( m_WaitersDone, m_pParent->mutex, false ); else WaitForSingleObject( m_pParent->mutex, INFINITE ); + + return true; } void EventImpl_Win32::Signal() diff --git a/stepmania/src/arch/Threads/Threads_Win32.h b/stepmania/src/arch/Threads/Threads_Win32.h index 1d3a9f8706..4537381876 100644 --- a/stepmania/src/arch/Threads/Threads_Win32.h +++ b/stepmania/src/arch/Threads/Threads_Win32.h @@ -46,7 +46,7 @@ public: EventImpl_Win32( MutexImpl_Win32 *pParent ); ~EventImpl_Win32(); - void Wait(); + bool Wait( RageTimer *pTimeout ); void Signal(); void Broadcast();