From 4738f31efd57805e4caab11e8e52b0f7e320cef8 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 6 Jul 2009 19:32:18 +0000 Subject: [PATCH] wait-with-timeout --- direct/src/plugin/p3dConditionVar.cxx | 48 ++++++++++++++++++++++++--- direct/src/plugin/p3dConditionVar.h | 1 + 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/direct/src/plugin/p3dConditionVar.cxx b/direct/src/plugin/p3dConditionVar.cxx index effe5c5c38..ccfe7d9b64 100644 --- a/direct/src/plugin/p3dConditionVar.cxx +++ b/direct/src/plugin/p3dConditionVar.cxx @@ -65,7 +65,8 @@ P3DConditionVar:: //////////////////////////////////////////////////////////////////// // Function: P3DConditionVar::acquire // Access: Public -// Description: +// Description: Acquires the internal lock. The lock should be held +// during any calls to wait() or notify(). //////////////////////////////////////////////////////////////////// void P3DConditionVar:: acquire() { @@ -82,7 +83,9 @@ acquire() { //////////////////////////////////////////////////////////////////// // Function: P3DConditionVar::wait // Access: Public -// Description: +// Description: Requires the lock to be held on entry. Releases the +// lock, waits for another thread to call notify(), then +// reacquires the lock on exit. //////////////////////////////////////////////////////////////////// void P3DConditionVar:: wait() { @@ -101,10 +104,47 @@ wait() { #endif // _WIN32 } +//////////////////////////////////////////////////////////////////// +// Function: P3DConditionVar::wait +// Access: Public +// Description: As above, but waits no longer than timeout seconds +// before returning. +//////////////////////////////////////////////////////////////////// +void P3DConditionVar:: +wait(double timeout) { +#ifdef _WIN32 + LeaveCriticalSection(&_lock); + + DWORD result = WaitForSingleObject(_event_signal, (DWORD)(timeout * 1000.0)); + assert(result == WAIT_OBJECT_0 || result == WAIT_TIMEOUT); + + EnterCriticalSection(&_lock); +#else // _WIN32 + + struct timeval now; + gettimeofday(&now, NULL); + + // Convert from timeval to timespec + struct timespec ts; + ts.tv_sec = now.tv_sec; + ts.tv_nsec = now.tv_usec * 1000; + + int seconds = (int)floor(timeout); + ts.tv_sec += seconds; + ts.tv_nsec += (int)((timeout - seconds) * 1000000.0); + + int result = pthread_cond_timedwait(&_cvar, &_lock, &ts); + assert(result == 0); + +#endif // _WIN32 +} + //////////////////////////////////////////////////////////////////// // Function: P3DConditionVar::notify // Access: Public -// Description: +// Description: Waits a single thread blocked on wait(), if any. If +// no threads are waiting, the event is lost. The lock +// should be held during this call. //////////////////////////////////////////////////////////////////// void P3DConditionVar:: notify() { @@ -121,7 +161,7 @@ notify() { //////////////////////////////////////////////////////////////////// // Function: P3DConditionVar::release // Access: Public -// Description: +// Description: Releases the internal lock. //////////////////////////////////////////////////////////////////// void P3DConditionVar:: release() { diff --git a/direct/src/plugin/p3dConditionVar.h b/direct/src/plugin/p3dConditionVar.h index 63fd77f48e..68e78edf1f 100644 --- a/direct/src/plugin/p3dConditionVar.h +++ b/direct/src/plugin/p3dConditionVar.h @@ -30,6 +30,7 @@ public: void acquire(); void wait(); + void wait(double timeout); void notify(); void release();