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

Detailed Description

Outline

Purpose

Provide a timed semaphore class.

Classes

See also
bslmt_semaphore

Description

This component defines a portable and efficient thread synchronization primitive. In particular, bslmt::TimedSemaphore is an efficient synchronization primitive that enables sharing of a counted number of resources or exclusive access.

bslmt::TimedSemaphore differs from bslmt::Semaphore in that the former supports a timedWait method, whereas the latter does not. In addition, bslmt::Semaphore has a getValue accessor, whereas bslmt::TimedSemaphore does not. In the case of the timed semaphore, getValue cannot be implemented efficiently on all platforms, so that method is intentionally not provided.

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).

On platforms that support bsl::chrono, there are constructors that take bsl::chrono-style clocks. If the clock type indicated at construction is bsl::chrono::system_clock, then the results will be the same as if bsls::SystemClockType::e_REALTIME was indicated. If the clock type indicated at construction is bsl::chrono::steady_clock, then the results will be the same as if bsls::SystemClockType::e_MONOTONIC was indicated. Constructing from a user-defined clock is not supported.

Usage

This section illustrates intended use of this component.

Example 1: Basic Usage

This example illustrates a very simple queue where potential clients can push integers to a queue, and later retrieve the integer values from the queue in FIFO order. It illustrates two potential uses of semaphores: to enforce exclusive access, and to allow resource sharing. This queue allows clients to set a limit on how long they wait to retrieve values.

/// FIFO queue of integer values.
class IntQueue {
// DATA
bsl::deque<int> d_queue; // underlying queue
bslmt::TimedSemaphore d_resourceSem; // resource-availability semaphore
bslmt::TimedSemaphore d_mutexSem; // mutual-access semaphore
// NOT IMPLEMENTED
IntQueue(const IntQueue&);
IntQueue& operator=(const IntQueue&);
public:
// CREATORS
/// Create an `IntQueue` object. Optionally specified a
/// `basicAllocator` used to supply memory. If `basicAllocator` is
/// 0, the currently installed default allocator is used.
explicit IntQueue(bslma::Allocator *basicAllocator = 0);
/// Destroy this `IntQueue` object.
~IntQueue();
// MANIPULATORS
/// Load the first integer in this queue into the specified `result`
/// and return 0 unless the operation takes more than the optionally
/// specified `maxWaitSeconds`, in which case return a nonzero value
/// and leave `result` unmodified.
int getInt(int *result, int maxWaitSeconds = 0);
/// Push the specified `value` to this `IntQueue` object.
void pushInt(int value);
};
Definition bslstl_deque.h:772
Definition bslma_allocator.h:457
Definition bslmt_timedsemaphore.h:221

Note that the IntQueue constructor increments the count of the semaphore to 1 so that values can be pushed into the queue immediately following construction:

// CREATORS
IntQueue::IntQueue(bslma::Allocator *basicAllocator)
: d_queue(basicAllocator)
, d_resourceSem(bsls::SystemClockType::e_MONOTONIC)
{
d_mutexSem.post();
}
IntQueue::~IntQueue()
{
d_mutexSem.wait(); // Wait for potential modifier.
}
// MANIPULATORS
int IntQueue::getInt(int *result, int maxWaitSeconds)
{
// Waiting for resources.
if (0 == maxWaitSeconds) {
d_resourceSem.wait();
} else {
.addSeconds(maxWaitSeconds);
int rc = d_resourceSem.timedWait(absTime);
if (0 != rc) {
return rc;
}
}
// 'd_mutexSem' is used for exclusive access.
d_mutexSem.wait(); // lock
*result = d_queue.back();
d_queue.pop_back();
d_mutexSem.post(); // unlock
return 0;
}
void IntQueue::pushInt(int value)
{
d_mutexSem.wait();
d_queue.pushFront(value);
d_mutexSem.post();
d_resourceSem.post(); // Signal that we have resources available.
}
Definition bsls_timeinterval.h:301
BSLS_KEYWORD_CONSTEXPR_CPP14 TimeInterval & addSeconds(bsls::Types::Int64 seconds)
Definition bsls_timeinterval.h:1122
Definition bdlt_iso8601util.h:691
static TimeInterval nowMonotonicClock()