RWCondition RWSynchObject
#include <rw/sync/RWCondition.h>
An RWCondition object is a condition variable that can be used to delay a thread until the program state satisfies some boolean condition, and to awaken that thread once the condition becomes true.
The name condition variable is perhaps a misnomer. The name seems to imply that a condition variable encapsulates a condition. This is not the case. A condition variable is associated with some arbitrary condition in a program. It simply provides a mechanism for threads to wait and signal. It is up to the programmer to code the application such that it waits at the appropriate point of execution when the condition is false, and to signal appropriately when the condition becomes true.
A condition variable must be initialized with a mutex. The mutex must be the same as is used to protect the program state involved in the condition test. To delay on a condition variable, a thread calls the wait() member. The wait() function atomically releases the lock and logically adds the thread to a list of threads that are waiting on the same condition. Another thread can unblock one waiting thread, if there are any, by calling the signal() member function. All waiting threads can be awakened at once by calling the signalAll() member function. For each awakened thread, the wait() function reacquires the lock and returns control to the calling routine.
To use an RWCondition object, a boolean expression is evaluated under the protection of a mutex lock. When the expression is false, the thread blocks on the condition variable and the mutex is released. The condition variable is then signaled by another thread following changes to the state being evaluated by the conditional expression. This causes one or all of the threads, depending on whether signal() or signalAll() is used, to block on the condition to awaken and to try to reacquire the lock.
A thread should always retest the condition when it is awakened, as the condition might have changed by the time it can reacquire the condition mutex. This is typically done in a loop:
while (!my_boolean_expression)
cv.wait();
When using RWCondition in a class inheriting from RWTMonitor<T>, it is not uncommon to initialize the RWCondition with the monitor's mutex.
#include <rw/sync/RWCondition.h> // for RWCondition #include <rw/sync/RWTMonitor.h> // for RWTMonitor<T> #include <rw/sync/RWMutexLock.h> // for RWMutexLock #include <rw/tvslist.h> // for RWTValSlist<T> // Producer Consumer queue example template <class T> class PCBuffer : RWTMonitor<RWMutexLock> { private: RWCondition roomInBuffer_; RWCondition elementAvailable_; RWTValSlist<T> buffer_; size_t maxEntries_; public: PCBuffer(size_t maxEntries) : maxEntries_(maxEntries), roomInBuffer_(mutex()), // init with monitor mutex elementAvailable_(mutex()) // init with monitor mutex {} void put(T t) { LockGuard lock(monitor()); // acquire monitor mutex while (!(buffer_.entries() < maxEntries_)) { roomInBuffer_.wait(); // mutex released automatically // thread must have been signaled AND // mutex reacquired to reach here } buffer_.append(t); elementAvailable_.signal(); // mutex automatically released in LockGuard destructor } T get(void) { LockGuard lock(monitor()); // acquire monitor mutex while (!(buffer_.entries() > 0)) { elementAvailable_.wait(); // mutex released //automatically // thread must have been signalled AND // mutex reacquired to reach here } T val = buffer_.removeFirst(); roomInBuffer_.signal(); return val; // mutex automatically released in LockGuard destructor } };
typedef pthread_cond_t RWConditionRep;
This is the internal condition variable representation, RWConditionRep, for POSIX.
typedef cond_t RWConditionRep;
This is the internal condition variable representation, RWConditionRep, for Solaris.
typedef RWTLockGuard<RWCondition> LockGuard; typedef RWTTryLockGuard<RWCondition> TryLockGuard; typedef RWTUnlockGuard<RWCondition> UnLockGuard;
Predefined types for compatible guards.
RWCondition(RWMutexLock& mutex, RWCancellationState state=RW_CANCELLATION_DISABLED);
Creates a condition variable that is protected by the supplied mutex instance. The provided mutex must exist as long as the condition variable exists. Possible exceptions include RWTHRResourceLimit and RWTHRInternalError.
~RWCondition();
The default destructor.
void acquire(void);
Blocks until the condition's mutex is released, acquires it, and continues. This function is provided as a convenience; you may also call the mutex acquire() function directly. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
RWWaitStatus acquire(unsigned long milliseconds);
Acquires the mutex associated with the condition variable. If the mutex is not available, blocks at least for the specified number of milliseconds, or until the mutex is released-whichever comes first. If the mutex is released within the specified time, acquires it, and continues. If the mutex is not released, returns the time-out indication RW_THR_TIMEOUT. This function is provided as a convenience; you may also call the mutex timed acquire() function directly. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
RWConditionRep* getConditionRep(void) const;
Solaris and POSIX only. Provides access to the underlying mechanism.
void release(void);
Releases the mutex associated with the condition variable. This function is provided as a convenience; you may also call the mutex release() function directly. Possible exceptions include RWTHRInternalError.
void signal(void);
Signals one waiting thread that the condition associated with the condition variable has changed. Possible exceptions include RWTHRInternalError.
void signalAll(void);
Signals all waiting threads that the condition associated with the condition variable has changed. Possible exceptions include RWTHRInternalError.
RWBoolean tryAcquire(void);
Tries to acquire the condition's mutex (without blocking), returning TRUE if acquired, or FALSE if the mutex is already owned by another thread. This function is provided as a convenience; you may also call the mutex tryAcquire() function directly. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
void wait(void);
Releases the condition mutex, then waits for a thread to signal that the state condition associated with the condition variable has changed. When a thread is woken up from waiting, the condition mutex is automatically reacquired. If another thread holds the mutex when the thread is woken up, then it must wait until it can acquire the mutex before proceeding. Possible exceptions include RWCancellation and RWTHRInternalError.
RWWaitStatus wait(unsigned long milliseconds);
Same as wait() except if the specified amount of time elapses before the thread signals, then RW_THR_TIMEOUT is returned. Otherwise, RW_THR_SIGNALED is returned when the thread is signalled that the state condition has changed. Note that if the wait times out, the function won't return until the condition mutex can be reacquired. Possible exceptions include RWCancellation and RWTHRInternalError.
RWCondition(const RWCondition& second);
Copy construction prohibited.
RWCondition& operator=(const RWCondition& second);
Assignment prohibited.
©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.