c++-gtk-utils
Public Member Functions | Static Public Member Functions | List of all members
Cgu::Thread::Cond Class Reference

A wrapper class for pthread condition variables. More...

#include <c++-gtk-utils/mutex.h>

Public Member Functions

 Cond (const Cond &)=delete
 
Condoperator= (const Cond &)=delete
 
int signal () noexcept
 
int broadcast () noexcept
 
int wait (Mutex &mutex)
 
int wait (Mutex::Lock &lock)
 
int wait (Mutex::TrackLock &lock)
 
int timed_wait (Mutex &mutex, const timespec &abs_time)
 
int timed_wait (Mutex::Lock &lock, const timespec &abs_time)
 
int timed_wait (Mutex::TrackLock &lock, const timespec &abs_time)
 
 Cond ()
 
 ~Cond (void)
 

Static Public Member Functions

static void get_abs_time (timespec &ts, unsigned int millisec)
 
static bool have_monotonic_clock ()
 

Detailed Description

A wrapper class for pthread condition variables.

See also
Thread::Thread Thread::Mutex Thread::Mutex::Lock Thread::Mutex::TrackLock

Constructor & Destructor Documentation

◆ Cond() [1/2]

Cgu::Thread::Cond::Cond ( const Cond )
delete

This class cannot be copied. The copy constructor is deleted.

◆ Cond() [2/2]

Cgu::Thread::Cond::Cond ( )

Initialises the pthread condition variable. It is not a cancellation point.

Exceptions
Cgu::Thread::CondErrorThrows this exception if initialization of the condition variable fails. (It is often not worth checking for CondError, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.)
Note
If the system supports monotonic clocks (and this library is not being cross-compiled onto a different architecture), then condition variables will use a system monotonic clock in Cond::timed_wait() and Cond::get_abs_time(). This can be tested at run time by calling Cond::have_monotonic_clock().

◆ ~Cond()

Cgu::Thread::Cond::~Cond ( void  )
inline

Destroys the pthread condition variable. It is not a cancellation point. The destructor does not throw. Destroying a condition variable on which another thread is currently blocked results in undefined behavior.

Member Function Documentation

◆ broadcast()

int Cgu::Thread::Cond::broadcast ( )
inlinenoexcept

Unblocks all threads waiting on this condition variable, which acquire the mutex in an order determined by the scheduling policy. Can be called by any thread. It is not a cancellation point. Does not throw.

Returns
0 if successful, otherwise the pthread error number.
Note
With this library implementation, no pthread error should arise so there is no need to check the return value.

◆ get_abs_time()

static void Cgu::Thread::Cond::get_abs_time ( timespec &  ts,
unsigned int  millisec 
)
static

This is a utility function that inserts into a timespec structure the current time plus a given number of milliseconds ahead, which can be applied to a call to Cond::timed_wait(). It does not throw. It is thread-safe.

Parameters
tsA timespec object into which the result of current time + millisec will be placed.
millisecThe number of milliseconds ahead of current time to which the timespec object will be set.
Note
If the system supports monotonic clocks (and this library is not being cross-compiled onto a different architecture), then condition variables will use a system monotonic clock in this method and Cond::timed_wait(). This can be tested at run time with Cond::have_monotonic_clock().

◆ have_monotonic_clock()

static bool Cgu::Thread::Cond::have_monotonic_clock ( )
static

Indicates whether the library has been compiled with support for monotonic clocks in Cond::timed_wait(). Most recent linux and BSD distributions will support them, and this function would normally return true unless the library has been cross-compiled from one platform to a different platform. This function can be tested at program initialization, and if they are not supported a warning can be given to the user about the deficiences of using the system clock for timed events. It does not throw. It is thread safe.

Returns
true if the library has been compiled with support for monotonic clocks in Cond::timed_wait(), otherwise false.

◆ operator=()

Cond& Cgu::Thread::Cond::operator= ( const Cond )
delete

This class cannot be copied. The assignment operator is deleted.

◆ signal()

int Cgu::Thread::Cond::signal ( )
inlinenoexcept

Unblock at least one thread waiting on this condition variable. Can be called by any thread. It is not a cancellation point. Does not throw.

Returns
0 if successful, otherwise the pthread error number.
Note
With this library implementation, no pthread error should arise so there is no need to check the return value.

◆ timed_wait() [1/3]

int Cgu::Thread::Cond::timed_wait ( Mutex mutex,
const timespec &  abs_time 
)
inline

Waits on this condition variable until awoken (in which case it re-acquires the mutex), or until the timeout expires (in which case it re-acquires the mutex and returns with ETIMEDOUT). It must be called by the thread which owns the mutex. Re-acquires the mutex when awoken or timing out. It is a cancellation point. This method is cancellation safe even if the stack does not unwind on cancellation (but if the stack does not unwind some other way of destroying this object on cancellation is required, such as by having it allocated on freestore and deleted in a cancellation clean-up handler). This method does not throw.

Parameters
mutexThe locked mutex associated with the wait which is re-acquired on being awoken or timing out.
abs_timeThe time at which the wait will unblock if not previously awoken. A suitable value can be obtained by calling the get_abs_time() function.
Returns
0 after being awoken on waiting, otherwise ETIMEDOUT or other pthread error number.
Note
1. With this library implementation, apart from ETIMEDOUT, the only pthread error numbers which could be returned are EINVAL (if the mutex argument is not a valid mutex or the abs_time argument does not comprise a valid timespec struct) or EPERM (if the thread calling this method does not own the mutex).
2. pthread condition variables can, as a matter of design, awake spontaneously (and Cond::signal() may awaken more than one thread). Therefore the relevant condition should be tested in a while loop and not in an if block. 0 will be returned on a spontaneous awakening.
3. If the system supports monotonic clocks (and this library is not being cross-compiled onto a different architecture), then condition variables will use a monotonic clock in Cond::timed_wait() and Cond::get_abs_time(). This can be tested at run time with Cond::have_monotonic_clock().
4. Between versions 2.2.3 and 2.2.13 inclusive, this method was marked 'noexcept'. This was a mistake because it prevented a thread being cancelled while in a wait (the cancellation pseudo-exception conflicted with the noexcept specifier). This was fixed in version 2.2.14.

◆ timed_wait() [2/3]

int Cgu::Thread::Cond::timed_wait ( Mutex::Lock lock,
const timespec &  abs_time 
)
inline

Does the same as Cond::timed_wait(Mutex&, const timespec&), except that as a convenience it will take a Mutex::Lock object handling the Mutex object as an alternative to passing the Mutex object itself.

Note
Between versions 2.2.3 and 2.2.13 inclusive, this method was marked 'noexcept'. This was a mistake because it prevented a thread being cancelled while in a wait (the cancellation pseudo-exception conflicted with the noexcept specifier). This was fixed in version 2.2.14.

◆ timed_wait() [3/3]

int Cgu::Thread::Cond::timed_wait ( Mutex::TrackLock lock,
const timespec &  abs_time 
)
inline

Does the same as Cond::timed_wait(Mutex&, const timespec&), except that as a convenience it will take a Mutex::TrackLock object handling the Mutex object as an alternative to passing the Mutex object itself.

Note
Between versions 2.2.3 and 2.2.13 inclusive, this method was marked 'noexcept'. This was a mistake because it prevented a thread being cancelled while in a wait (the cancellation pseudo-exception conflicted with the noexcept specifier). This was fixed in version 2.2.14.

◆ wait() [1/3]

int Cgu::Thread::Cond::wait ( Mutex mutex)
inline

Waits on this condition variable until awoken. It must be called by the thread which owns the mutex. Re-acquires the mutex when awoken. It is a cancellation point. This method is cancellation safe even if the stack does not unwind on cancellation (but if the stack does not unwind some other way of destroying this object on cancellation is required, such as by having it allocated on freestore and deleted in a cancellation clean-up handler). This method does not throw.

Parameters
mutexThe locked mutex associated with the wait which is re-acquired on being awoken.
Returns
0 after being awoken on waiting, otherwise the pthread error number.
Note
1. pthread condition variables can, as a matter of design, awake spontaneously (and Cond::signal() may awaken more than one thread). Therefore the relevant condition should be tested in a while loop and not in an if block. 0 will be returned on a spontaneous awakening.
2. With this library implementation, the only pthread error numbers which could be returned are EINVAL (if the mutex argument is not a valid mutex) or EPERM (if the thread calling this method does not own the mutex).
3. Between versions 2.2.3 and 2.2.13 inclusive, this method was marked 'noexcept'. This was a mistake because it prevented a thread being cancelled while in a wait (the cancellation pseudo-exception conflicted with the noexcept specifier). This was fixed in version 2.2.14.

◆ wait() [2/3]

int Cgu::Thread::Cond::wait ( Mutex::Lock lock)
inline

Does the same as Cond::wait(Mutex&), except that as a convenience it will take a Mutex::Lock object handling the Mutex object as an alternative to passing the Mutex object itself.

Note
Between versions 2.2.3 and 2.2.13 inclusive, this method was marked 'noexcept'. This was a mistake because it prevented a thread being cancelled while in a wait (the cancellation pseudo-exception conflicted with the noexcept specifier). This was fixed in version 2.2.14.

◆ wait() [3/3]

int Cgu::Thread::Cond::wait ( Mutex::TrackLock lock)
inline

Does the same as Cond::wait(Mutex&), except that as a convenience it will take a Mutex::TrackLock object handling the Mutex object as an alternative to passing the Mutex object itself.

Note
Between versions 2.2.3 and 2.2.13 inclusive, this method was marked 'noexcept'. This was a mistake because it prevented a thread being cancelled while in a wait (the cancellation pseudo-exception conflicted with the noexcept specifier). This was fixed in version 2.2.14.

The documentation for this class was generated from the following file: