rwlogo
SourcePro C++ 12.0

SourcePro® C++ API Reference Guide



   SourcePro C++
Documentation Home

RWCondition Class Reference
[Synchronization]

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

List of all members.

Public Types

typedef RWTLockGuard< RWConditionLockGuard
typedef RWTTryLockGuard
< RWCondition
TryLockGuard
typedef RWTUnlockGuard
< RWCondition
UnlockGuard

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)

Protected Member Functions

RWMutexLockmutex () const

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 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 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<T> , it is not uncommon to initialize the RWCondition with the monitor's mutex.

Examples

 #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
    }
    };

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

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.

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.

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 [inline, protected]

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.

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.

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.


Friends And Related Function Documentation

typedef cond_t RWConditionRep [related]

Typedef for the internal condition variable.

Condition:
This type is used for build configurations based on Solaris threads.
typedef pthread_cond_t RWConditionRep [related]

Typedef for the internal condition variable.

Condition:
This type is used for build configurations based on POSIX threads.
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends

© Copyright Rogue Wave Software, Inc. All Rights Reserved.
Rogue Wave and SourcePro are registered trademarks of Rogue Wave Software, Inc. in the United States and other countries. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.