SourcePro® API Reference Guide

 
List of all members | Public Types | Public Member Functions | Protected Member Functions | Private Member Functions | Related Functions
RWCondition Class Reference

A condition variable used to delay and reawaken a thread based on program state. More...

#include <rw/sync/RWCondition.h>

Inheritance diagram for RWCondition:
RWSynchObject

Public Types

typedef RWTLockGuard< RWConditionLockGuard
 
typedef RWTTryLockGuard< RWConditionTryLockGuard
 
typedef RWTUnlockGuard< RWConditionUnlockGuard
 

Public Member Functions

 RWCondition (RWMutexLock &mutex, RWCancellationState state=0)
 
 ~RWCondition ()
 
void acquire ()
 
RWWaitStatus acquire (unsigned long milliseconds)
 
RWConditionRepgetConditionRep () const
 
void release ()
 
void signal ()
 
void signalAll ()
 
bool tryAcquire ()
 
void wait ()
 
RWWaitStatus wait (unsigned long milliseconds)
 
- Public Member Functions inherited from RWSynchObject
void disableCancellation ()
 
void enableCancellation (RWCancellationState)
 
bool isCancellationEnabled () const
 
void setCancellation (RWCancellationState)
 

Protected Member Functions

RWMutexLockmutex () const
 
- Protected Member Functions inherited from RWSynchObject
 RWSynchObject (RWCancellationState state=0)
 
 RWSynchObject (RWStaticCtor)
 
 RWSynchObject (const RWSynchObject &second)
 
RWSynchObjectoperator= (const RWSynchObject &second)
 
void testCancellation ()
 

Private Member Functions

 RWCondition (const RWCondition &second)
 
RWConditionoperator= (const RWCondition &second)
 

Related Functions

(Note that these are not member functions.)

typedef pthread_cond_t RWConditionRep
 
typedef cond_t RWConditionRep
 

Detailed Description

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 application to wait 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 instance that is used to protect the program state involved in the condition test. To delay on a condition variable, a thread calls the wait() function which 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 thread evaluates a boolean expression under the protection of a mutex lock. When the expression is false, the thread blocks on the condition variable, and the mutex is released. Later, when another thread changes the state of the conditional expression under protection of the mutex lock, it then signals that the condition state has changed. This causes one or all 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 before the thread 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, it is not uncommon to initialize the RWCondition with the monitor's mutex.

Example
#include <rw/sync/RWCondition.h>
#include <rw/sync/RWTMonitor.h>
#include <rw/sync/RWMutexLock.h>
#include <rw/tvslist.h>
// 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
}
};

Member Typedef Documentation

Predefined type for compatible guard.

Predefined type for compatible guard.

Predefined type for compatible guard.

Constructor & Destructor Documentation

RWCondition::RWCondition ( RWMutexLock mutex,
RWCancellationState  state = 0 
)

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::~RWCondition ( )

Default destructor.

RWCondition::RWCondition ( const RWCondition second)
private

Assignment prohibited.

Member Function Documentation

void RWCondition::acquire ( void  )
inline

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.

This function does not block in single-threaded builds. The underlying mutex acquire returns immediately to indicate success. If the mutex was unavailable for acquisition, a debug assertion will result or an RWTHRInternalError will be thrown.

RWWaitStatus RWCondition::acquire ( unsigned long  milliseconds)
inline

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, the function acquires it and continues. If the mutex is not released, the function 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.

This function does not block in single-threaded builds. The underlying mutex acquire returns immediately.

RWConditionRep* RWCondition::getConditionRep ( ) const

Provides access to the underlying mechanism.

Condition:
This function is available only in build configurations based on POSIX or Solaris threads.
RWMutexLock & RWCondition::mutex ( void  ) const
inlineprotected

Returns a reference to the mutex associated with this condition variable.

RWCondition& RWCondition::operator= ( const RWCondition second)
private

Copy construction prohibited.

void RWCondition::release ( )
inline

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 RWCondition::signal ( )

Signals one waiting thread that the condition associated with the condition variable has changed. Possible exceptions include RWTHRInternalError.

This function is a no-op in single-threaded builds.

void RWCondition::signalAll ( )

Signals all waiting threads that the condition associated with the condition variable has changed. Possible exceptions include RWTHRInternalError.

This function is a no-op in single-threaded builds.

bool RWCondition::tryAcquire ( )
inline

Tries to acquire the condition's mutex (without blocking). Returns 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 RWCondition::wait ( )

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 has been awakened, the condition mutex is automatically reacquired. If another thread holds the mutex when the thread awakes, then the thread must wait until it can acquire the mutex before proceeding. Possible exceptions include RWCancellation and RWTHRInternalError.

Calling this function produces an assertion in single-threaded debug mode builds, and an RWTHRInternalError is thrown in release builds.

RWWaitStatus RWCondition::wait ( unsigned long  milliseconds)

This function is similar to wait(), but returns RW_THR_TIMEOUT if the specified amount of time elapses before the thread signals. Otherwise, returns RW_THR_SIGNALED when the thread is signaled 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.

This function immediately returns RW_THR_TIMEOUT in single-threaded builds.

Friends And Related Function Documentation

typedef pthread_cond_t RWConditionRep
related

Typedef for the internal condition variable.

Condition:
This type is used for build configurations based on POSIX threads.
typedef cond_t RWConditionRep
related

Typedef for the internal condition variable.

Condition:
This type is used for build configurations based on Solaris threads.

Copyright © 2023 Rogue Wave Software, Inc., a Perforce company. All Rights Reserved.