|
BDE 4.14.0 Production release
|
Provide utilities related to threading with C++11-style clocks.
bsl::chrono-related operationsThis component defines a utility struct, bslmt::ChronoUtil, that serves as a namespace for a suite of classes and functions for interfacing C++11-style clocks with the clocks that BDE provides.
bslmt::ChronoUtil defines a durationToTimeInterval function for converting an arbitrary bsl::chrono::duration to a bsls::TimeInterval.
bslmt::ChronoUtil also defines a timedWait function for waiting on a synchronization primitive that uses a bsls system clock type internally (see bsls_systemclocktype ), while allowing the user to specify the timeout using a bsl::chrono::time_point.
ChronoUtil::timedWait requires several things from the underlying primitive:
(1) an enumeration containing e_TIMED_OUT.
(2) a member function, timedWait, that takes a const bsls::TimeInterval& denoting the timeout value, and possibly an additional pointer argument. This function should return 0 upon success, e_TIMED_OUT on a timeout, and some other value on failure. ChronoUtil::timedWait will convert the bsl::chrono::time_point that is passed to it into a bsls::TimeInterval that can be used by the synchronization primitive (ARG_TYPE is just a placeholder name; the primitive will have its own type):
(3) a const member function, clockType, that takes no parameters and returns the underlying clock that the primitive uses – either bsls::SystemClockType::e_REALTIME or bsls::SystemClockType::e_MONOTONIC:
Note that if the clock associated with the time point does not correspond to the clock used by the underlying synchronization primitive, then the timedWait function of the primitive may be called more than once, so the method is potentially more efficient if the clocks match.
Finally, bslmt::ChronoUtil defines an isMatchingClock function that checks to see if a C++11-style clock matches a bsls system clock. See bsls_systemclocktype .
This example illustrates intended use of this component.
We first define a synchronization primitive that is compliant with the requirements of bslmt::ChronoUtil::timedWait and then demonstrate use of that primitive with timedWait.
The TimedWaitSuccess class, defined below, is a synchronization primitive that complies with the requirements of bslmt::ChronoUtil::timedWait (see the component-level documentation for information).
First, we define the interface of TimedWaitSuccess:
Then, we implement the creator. All it has to do is remember the clockType that was passed to it:
Next, we implement the timedWait function. In this simplistic primitive, this function always succeeds:
Next, we implement the clockType function, which returns the underlying bsls::SystemClockType::Enum that this primitive uses:
This example demonstrates use of bslmt::ChronoUtil::timedWait to block on a synchronization primitive until either a condition is satisfied or a specified amount of time has elapsed. We use a bsl::chrono::time_point to specify the amount of time to wait. To do this, we call bslmt::ChronoUtil::timedWait, passing in the timeout as an absolute time point. In this example, we're using TimedWaitSuccess as the synchronization primitive, and specifying the timeout using bsl::chrono::steady_clock.
First, we construct the TimedWaitSuccess primitive; by default it uses the bsls realtime system clock to measure time:
Then, we call bslmt::ChronoUtil::timedWait to block on aPrimitive, while passing a timeout of "10 seconds from now", measured on the bsl::chrono::steady_clock:
When this call returns, one of three things will be true: (a) rc == 0, which means that the call succeeded before the timeout expired, (b) rc == TimedWaitSuccess::e_TIMED_OUT, which means that the call did not succeed before the timeout expired, or (c) rc equals some other value, which means that an error occurred.
If the call to bslmt::ChronoUtil::timedWait returned e_TIMED_OUT then we are guaranteed that the current time on the clock that the time point was defined on is greater than the timeout value that was passed in.