/* ==================================================================== * Copyright (c) 2003-2006, The Subcommander Crew * http://subcommander.tigris.org * * Subcommander is licensed as described in the file doc/COPYING, which * you should have received as part of this distribution. * ==================================================================== */ // sc #include "Condition.h" #include "Guard.h" // apr #include namespace sc { /** * Create a condition variable. */ Condition::Condition() : _c(false) { apr_thread_cond_create( &_condition, _pool ); } /** * Clean up. */ Condition::~Condition() { apr_thread_cond_destroy(_condition); } /** * Wake up a single waiting thread. * \sa wakeAll() */ void Condition::wakeOne() { Guard guard(_mutex); _c = true; apr_thread_cond_signal(_condition); } /** * Wake up all waiting threads. * \sa wait() */ void Condition::wakeAll() { Guard guard(_mutex); _c = true; apr_thread_cond_broadcast(_condition); } /** * Wait for the condition. This call blocks until the condition is set. */ void Condition::wait() { Guard guard(_mutex); // the loop handles 2 special cases: // 1. don't block the calling thread if the condition is already set. // 2. only return if the condition is set. The condition may be reset // before the waking thread reaquires the mutex. (is that correct?) while( ! _c ) { apr_thread_cond_wait( _condition, _mutex._mutex ); } } /** * Wait for the condition. This call blocks until the condition is set * (returns true) or a time span of microsec has elapsed (returns false). */ bool Condition::wait( unsigned long millies ) { Guard guard(_mutex); while( ! _c ) { apr_status_t status = apr_thread_cond_timedwait( _condition, _mutex._mutex, millies*1000 ); if( status == APR_TIMEUP ) { return false; } } return true; } /** * Reset the condition. */ void Condition::reset() { Guard guard(_mutex); _c = false; } } // namespace