BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmt_condition

Detailed Description

Outline

Purpose

Provide a portable, efficient condition variable.

Classes

See also
bslmt_mutex

Description

The bslmt::Condition class provided by this component implements the concept of a condition variable, enabling multiple threads to communicate information about the state of shared data. A condition variable is a signaling mechanism associated with a mutex, which in turn protects a data invariant. A condition variable enables threads to wait for a predicate (i.e., logical expression) to become true, and to communicate to other threads that the predicate might be true.

One or more threads can wait efficiently on a condition variable, either indefinitely or until some absolute time, by invoking one of the following methods of bslmt::Condition:

int wait(bslmt::Mutex *mutex);
int timedWait(bslmt::Mutex *mutex, const bsls::TimeInterval& absTime);
Definition bslmt_mutex.h:315
Definition bsls_timeinterval.h:301

The caller must lock the mutex before invoking these functions. The bslmt::Condition atomically releases the lock and waits, thereby preventing other threads from changing the predicate after the lock is released, but before the thread begins to wait. The bslmt package guarantees that this lock will be reacquired before returning from a call to the wait and timedWait methods, unless an error occurs.

When invoking the timedWait method, clients must specify, via the parameter absTime, a timeout after which the call will return even if the condition is not signaled. absTime is expressed as a bsls::TimeInterval object that holds an absolute time according to the clock type the bslmt::Condition object is constructed with (the default clock is bsls::SystemClockType::e_REALTIME). Clients should use the bsls::SystemTime::now(clockType) utility method to obtain the current time.

Other threads can indicate that the predicate is true by signaling or broadcasting the same bslmt::Condition object. A broadcast wakes up all waiting threads, whereas a signal wakes only one thread. The client has no control over which thread will be signaled if multiple threads are waiting:

void signal();
void broadcast();

A thread waiting on a condition variable may be signaled (i.e., the thread may wake up without an error), but find that the predicate is still false. This situation can arise for a few reasons: spurious wakeups produced by the operating system, intercepted wakeups, and loose predicates. Therefore, a waiting thread should always check the predicate after (as well as before) the call to the wait function.

Supported Clock-Types

bsls::SystemClockType supplies the enumeration indicating the system clock on which timeouts supplied to other methods should be based. If the clock type indicated at construction is bsls::SystemClockType::e_REALTIME, the absTime argument passed to the timedWait method should be expressed as an absolute offset since 00:00:00 UTC, January 1, 1970 (which matches the epoch used in bsls::SystemTime::now(bsls::SystemClockType::e_REALTIME). If the clock type indicated at construction is bsls::SystemClockType::e_MONOTONIC, the absTime argument passed to the timedWait method should be expressed as an absolute offset since the epoch of this clock (which matches the epoch used in bsls::SystemTime::now(bsls::SystemClockType::e_MONOTONIC).

Usage

This section illustrates intended use of this component.

Example 1: Basic Usage

Suppose we have a bslmt::Condition object, condition, and a boolean predicate associated with condition (represented here as a free function that returns a bool value):

/// Return `true` if the invariant holds for `condition`, and `false`
/// otherwise.
bool predicate()
{
return true;
}

The following usage pattern should always be followed:

// ...
bslmt::Condition condition;
mutex.lock();
while (false == predicate()) {
condition.wait(&mutex);
}
// Modify shared resources and adjust the predicate here.
mutex.unlock();
// ...
Definition bslmt_condition.h:220
int wait(Mutex *mutex)
Definition bslmt_condition.h:423
void lock()
Definition bslmt_mutex.h:392
void unlock()
Definition bslmt_mutex.h:410

The usage pattern for a timed wait is similar, but has extra branches to handle a timeout:

// ...
enum { e_TIMED_OUT = -1 };
// Advance 'absTime' to some delta into the future here.
mutex.lock();
while (false == predicate()) {
const int status = condition.timedWait(&mutex, absTime);
if (e_TIMED_OUT == status) {
break;
}
}
if (false == predicate()) {
// The wait timed out and `predicate` returned `false`. Perform
// timeout logic here.
// ...
}
else {
// The condition variable was either signaled or timed out and
// `predicate` returned `true`. Modify shared resources and adjust
// predicate here.
// ...
}
mutex.unlock();
// ...
int timedWait(Mutex *mutex, const bsls::TimeInterval &absTime)
Definition bslmt_condition.h:401
static TimeInterval nowRealtimeClock()