cppthread 1.1.16
C++ Thread Library
Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
cppthread::fifo< T > Class Template Reference

Create a thread safe FIFO. More...

Inheritance diagram for cppthread::fifo< T >:
Inheritance graph
[legend]
Collaboration diagram for cppthread::fifo< T >:
Collaboration graph
[legend]

Classes

struct  item_has_predicate
 
struct  item_has_predicate< C, R(A...), void_t< decltype(std::declval< C >().valid_workload(std::declval< A >()...))> >
 

Public Types

typedef std::vector< mutexdirect_vector_t
 A vector of mutexes.
 
typedef fifo< value_typefifo_type
 The type of the FIFO as a typedef.
 
typedef std::shared_ptr< fifo_typepointer_t
 A smart pointer to the FIFO.
 
typedef T value_type
 The type of value to push and pop from the FIFO.
 
typedef std::vector< pointer_tvector_t
 A vector of mutexes.
 

Public Member Functions

void broadcast ()
 Broadcast a mutex signal.
 
size_t byte_size () const
 Return the total size of the FIFO uses in memory.
 
void clear ()
 Clear the current FIFO.
 
bool dated_wait (std::uint64_t const date)
 Wait on a mutex until the specified date.
 
bool dated_wait (timespec const &date)
 Wait on a mutex until the specified date.
 
void done (bool clear)
 Mark the FIFO as done.
 
bool empty () const
 Test whether the FIFO is empty.
 
bool is_done () const
 Check whether the FIFO was marked as done.
 
void lock ()
 Lock a mutex.
 
bool pop_front (T &v, int64_t const usecs)
 Retrieve one value from the FIFO.
 
bool push_back (T const &v)
 Push data on this FIFO.
 
void safe_broadcast ()
 Broadcast a mutex signal.
 
void safe_signal ()
 Signal a mutex.
 
void signal ()
 Signal at least one mutex.
 
size_t size () const
 Return the number of items in the FIFO.
 
bool timed_wait (std::uint64_t const usec)
 Wait on a mutex condition with a time limit.
 
bool timed_wait (timespec const &nsec)
 Wait on a mutex condition with a time limit.
 
bool try_lock ()
 Try locking the mutex.
 
void unlock ()
 Unlock a mutex.
 
void wait ()
 Wait on a mutex condition.
 

Private Types

typedef std::deque< Titems_t
 The container type of our items.
 
template<typename ... >
using void_t = void
 

Private Member Functions

template<typename C >
std::enable_if<!snapdev::is_shared_ptr< C >::value &&item_has_predicate< C, bool()>::value, bool >::type validate_item (C const &item)
 Validate item.
 
template<typename C >
std::enable_if<!snapdev::is_shared_ptr< C >::value &&!item_has_predicate< C, bool()>::value, bool >::type validate_item (C const &item)
 Validate item.
 
template<typename C >
std::enable_if< snapdev::is_shared_ptr< C >::value &&item_has_predicate< typenameC::element_type, bool()>::value, bool >::type validate_item (C const &item)
 Validate item.
 
template<typename C >
std::enable_if< snapdev::is_shared_ptr< C >::value &&!item_has_predicate< typenameC::element_type, bool()>::value, bool >::type validate_item (C const &item)
 Validate item.
 

Private Attributes

bool f_broadcast = false
 Whether the done() function called broadcast().
 
bool f_done = false
 Whether the FIFO is done.
 
std::shared_ptr< detail::mutex_implf_impl
 The pthread mutex implementation.
 
items_t f_queue = items_t()
 The actual FIFO.
 
std::uint32_t f_reference_count = 0
 The lock reference count.
 

Detailed Description

template<class T>
class cppthread::fifo< T >

This template defines a thread safe FIFO which is also a mutex. You should use this snap_fifo object to lock your thread and send messages/data across various threads. The FIFO itself is a mutex so you can use it to lock the threads as with a normal mutex:

{
cppthread::snap_lock lock(f_messages);
...
}
std::enable_if<!snapdev::is_shared_ptr< C >::value &&item_has_predicate< C, bool()>::value, bool >::type validate_item(C const &item)
Validate item.
Definition fifo.h:101
void lock()
Lock a mutex.
Definition mutex.cpp:369
Note
It is recommended that you use a smart pointer to your data as the type T. This way you do not have to deal with copies in these FIFOs. However, if your data is very small (a few integers, a small string or two) then you may also use a type T which will be shared by copy. A smart pointer, thou
Template Parameters
Tthe type of data that the FIFO will handle.

Definition at line 57 of file fifo.h.

Member Typedef Documentation

◆ direct_vector_t

This type defines a vector of direct mutexes (i.e. not pointers to mutexes). This type can be used when you know the number of mutexes to allocate. Dynamically adding/removing mutexes with this type can be rather complicated.

Definition at line 59 of file mutex.h.

◆ fifo_type

template<class T >
cppthread::fifo< T >::fifo_type

This is a declaration of the FIFO type from the template type T. It can be useful in meta programming.

Definition at line 169 of file fifo.h.

◆ items_t

template<class T >
cppthread::fifo< T >::items_t
private

All of the FIFO items are pushed and popped from this type of container.

Definition at line 61 of file fifo.h.

◆ pointer_t

template<class T >
cppthread::fifo< T >::pointer_t

You may want to create FIFOs on the heap in which case we strongly advice that you use this shared pointer type to old those FIFOs.

It is otherwise possible to have the FIFO as a variable member of your thread. One thing to consider, though, if that if thread A owns a FIFO and shares it with thread B, then you must make sure that B is done before destroying A.

Definition at line 170 of file fifo.h.

◆ value_type

template<class T >
cppthread::fifo< T >::value_type

This typedef returns the type T of the template.

Definition at line 168 of file fifo.h.

◆ vector_t

This type defines a vector that can be used to manage mutexes. In this case, the mutexes must be allocated.

Definition at line 58 of file mutex.h.

◆ void_t

template<class T >
template<typename ... >
using cppthread::fifo< T >::void_t = void
private

Definition at line 65 of file fifo.h.

Member Function Documentation

◆ broadcast()

void cppthread::mutex::broadcast ( )
inherited

Our mutexes include a condition that get signaled by calling this function. This function actually signals all the threads that are currently listening to the mutex signal. The order in which the threads get awaken is unspecified.

The function ensures that the mutex is locked before broadcasting the signal so you do not have to lock the mutex yourself.

Note
We also offer a safe_broadcast(). If you expect absolutely all the other threads to receive the signal, then make sure to use the safe_broadcast() function instead. However, if you are already in a guarded block, then there is no need for an additional lock and this function will work exactly as expected.
Exceptions
cppthread_exception_invalid_errorIf one of the pthread system functions return an error, the function raises this exception.
See also
safe_broadcast()

Definition at line 838 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, cppthread::mutex::lock(), and cppthread::log.

Referenced by cppthread::fifo< T >::done(), and cppthread::fifo< T >::pop_front().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ byte_size()

template<class T >
cppthread::fifo< T >::byte_size ( ) const
inline

This function returns the sum of each element size() function.

Note
This calculation does not include the amount of bytes used by the FIFO itself. It only includes the size of the elements, which in most cases is what you want anyway.

The complexity of this function is O(n).

Returns
the byte size of the FIFO.

Definition at line 267 of file fifo.h.

References cppthread::fifo< T >::f_queue, cppthread::mutex::lock(), and cppthread::fifo< T >::validate_item().

Here is the call graph for this function:

◆ clear()

template<class T >
cppthread::fifo< T >::clear ( )
inline

This function can be used to clear the FIFO. Right after this call, the FIFO will be empty. All the objects that were pushed in the FIFO will be removed. It is your responsibility to ensure they get cleaned up appropriately.

Note
This function is often used along the done() function to quickly terminate threads.
See also
done()

Definition at line 248 of file fifo.h.

References cppthread::fifo< T >::empty(), cppthread::fifo< T >::f_queue, and cppthread::mutex::lock().

Referenced by cppthread::fifo< T >::done().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dated_wait() [1/2]

bool cppthread::mutex::dated_wait ( std::uint64_t const  usec)
inherited

This function waits on the mutex condition to be signaled up until the specified date is passed.

Warning
This function cannot be called if the mutex is not locked or the wait will fail in unpredictable ways.
Exceptions
cppthread_exception_mutex_failed_errorThis exception is raised whenever the thread wait function fails.
Parameters
[in]usecThe date when the mutex times out in microseconds.
Returns
true if the condition occurs before the function times out, false if the function times out.

Definition at line 642 of file mutex.cpp.

References cppthread::mutex::dated_wait().

Referenced by cppthread::mutex::dated_wait().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dated_wait() [2/2]

bool cppthread::mutex::dated_wait ( timespec const &  date)
inherited

This function waits on the mutex condition to be signaled up until the specified date is passed.

Warning
This function cannot be called if the mutex is not locked or the wait will fail in unpredictable ways.
Exceptions
cppthread_exception_mutex_failed_errorThis exception is raised whenever the thread wait function fails.
Parameters
[in]dateThe date when the mutex times out in nanoseconds.
Returns
true if the condition occurs before the function times out, false if the function times out.

Definition at line 668 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, and cppthread::log.

Here is the call graph for this function:

◆ done()

template<class T >
cppthread::fifo< T >::done ( bool  clear)
inline

By default the FIFO is not done. Once you are finished with it and will never push any more data to it, call this function. This flag is used by worker threads to know whether they should wait for more data or just exit.

This is rarely used with regular threads. It is more of a feature for worker threads.

Note
If the FIFO is empty, this function also broadcasts a signal to all the worker threads so that way they can exit.
Parameters
[in]clearWhether the function should also call clear()
See also
clear()

Definition at line 280 of file fifo.h.

References cppthread::mutex::broadcast(), cppthread::fifo< T >::clear(), cppthread::fifo< T >::empty(), cppthread::fifo< T >::f_broadcast, cppthread::fifo< T >::f_done, cppthread::fifo< T >::f_queue, and cppthread::mutex::lock().

Here is the call graph for this function:

◆ empty()

template<class T >
cppthread::fifo< T >::empty ( ) const
inline

This function checks whether the FIFO is empty and if so returns true, otherwise it returns false.

The function does not check the semaphore. Instead it checks the size of the FIFO itself.

Returns
true if the FIFO is empty.

Definition at line 255 of file fifo.h.

References cppthread::fifo< T >::f_queue, and cppthread::mutex::lock().

Referenced by cppthread::fifo< T >::clear(), and cppthread::fifo< T >::done().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_done()

template<class T >
cppthread::fifo< T >::is_done ( ) const
inline

When a child process calls pop_front() and the function returns false, it means the FIFO is empty. On return, the thread may then check whether is_done() is true. If so, then the thread is expected to exit (no more data will even be added to the FIFO so you might as well leave.)

Returns
true if the thread is expected to exit, false while still running.

Definition at line 296 of file fifo.h.

References cppthread::fifo< T >::f_done, and cppthread::mutex::lock().

Here is the call graph for this function:

◆ lock()

void cppthread::mutex::lock ( )
inherited

This function locks the mutex. The function waits until the mutex is available if it is not currently available. To avoid waiting one may want to use the try_lock() function instead.

Although the function cannot fail, the call can lock up a process if two or more mutexes are used and another thread is already waiting on this process.

Exceptions
cppthread_exception_invalid_errorIf the lock fails, this exception is raised.

Definition at line 369 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, cppthread::mutex::f_reference_count, and cppthread::log.

Referenced by cppthread::guard::guard(), cppthread::mutex::broadcast(), cppthread::fifo< T >::byte_size(), cppthread::fifo< T >::clear(), cppthread::fifo< T >::done(), cppthread::fifo< T >::empty(), cppthread::fifo< T >::is_done(), cppthread::guard::is_locked(), cppthread::guard::lock(), cppthread::fifo< T >::pop_front(), cppthread::fifo< T >::push_back(), cppthread::mutex::safe_broadcast(), cppthread::mutex::safe_signal(), and cppthread::fifo< T >::size().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pop_front()

template<class T >
cppthread::fifo< T >::pop_front ( T v,
int64_t const  usecs 
)
inline

This function retrieves one value from the thread FIFO. If necessary, the function can wait for a value to be received. The wait works as defined in the semaphore wait() function:

  • -1 – wait forever (use with caution as this prevents the STOP event from working.)
  • 0 – do not wait if there is no data, return immediately
  • +1 and more – wait that many microseconds

If the function works (returns true,) then v is set to the value being popped. Otherwise v is not modified and the function returns false.

Note
Because of the way the pthread conditions are implemented it is possible that the condition was already raised when you call this function. This means the wait, even if you used a value of -1 or 1 or more, will not happen.
If the function returns false, v is not set to anything so it still has the value it had when calling the function.
Parameters
[out]vThe value read.
[in]usecsThe number of microseconds to wait.
Returns
true if a value was popped, false otherwise.

Definition at line 184 of file fifo.h.

References cppthread::mutex::broadcast(), cppthread::fifo< T >::f_broadcast, cppthread::fifo< T >::f_done, cppthread::fifo< T >::f_queue, cppthread::mutex::lock(), cppthread::mutex::timed_wait(), cppthread::fifo< T >::validate_item(), and cppthread::mutex::wait().

Here is the call graph for this function:

◆ push_back()

template<class T >
cppthread::fifo< T >::push_back ( T const v)
inline

This function appends data on the FIFO queue. The function has the side effect to wake up another thread if such is currently waiting for data on the same FIFO.

Note
You can also wake up the other thread by calling the signal() function directly. This is especially useful after you marked the FIFO as done to make sure that all the worker threads wake up and exit cleanly.
Attention
Remember that if a thread is not currently waiting on the signal, calling signal is not likely to do anything except for the one next thread that waits on that signal.
Exceptions
cppthread_exception_invalid_errorDo not call this function after calling done(), it will raise this exception if you do so.
Parameters
[in]vThe value to be pushed on the FIFO queue.
Returns
true if the value was pushed, false otherwise.
See also
done()

Definition at line 172 of file fifo.h.

References cppthread::fifo< T >::f_done, cppthread::fifo< T >::f_queue, cppthread::mutex::lock(), and cppthread::mutex::signal().

Here is the call graph for this function:

◆ safe_broadcast()

void cppthread::mutex::safe_broadcast ( )
inherited

Our mutexes include a condition that get signaled by calling this function. This function actually signals all the threads that are currently listening to the mutex signal. The order in which the threads get awaken is unspecified.

The function ensures that the mutex is locked before broadcasting the signal so you do not have to lock the mutex yourself. Note that is not required to lock a mutex before broadcasting a signal. The effects are similar.

Exceptions
cppthread_exception_invalid_errorIf one of the pthread system functions return an error, the function raises this exception.
See also
broadcast()

Definition at line 799 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, cppthread::mutex::lock(), and cppthread::log.

Here is the call graph for this function:

◆ safe_signal()

void cppthread::mutex::safe_signal ( )
inherited

Our mutexes include a condition that get signaled by calling this function. This function wakes up one listening thread.

The function ensures that the mutex is locked before sending the signal so you do not have to lock the mutex yourself.

Exceptions
cppthread_exception_invalid_errorIf one of the pthread system functions return an error, the function raises this exception.
See also
signal()

Definition at line 765 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, cppthread::mutex::lock(), and cppthread::log.

Here is the call graph for this function:

◆ signal()

void cppthread::mutex::signal ( )
inherited

Our mutexes include a condition that get signaled by calling this function. This function wakes up one or more listening threads.

The function does not lock the mutext before sending the signal. This is useful if you already are in a guarded block or you do not mind waking up more than one thread as a result of the call.

Note
If you need to wake up exactly one other thread, then make sure to use the safe_signal() function instead.
Exceptions
cppthread_exception_invalid_errorIf one of the pthread system functions return an error, the function raises this exception.
See also
safe_signal()

Definition at line 737 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, and cppthread::log.

Referenced by cppthread::thread::internal_thread(), and cppthread::fifo< T >::push_back().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ size()

template<class T >
cppthread::fifo< T >::size ( ) const
inline

This function returns the number of items currently added to the FIFO. This can be used by the caller to avoid flooding the FIFO, if at all possible.

The complexity of this function is O(1).

Returns
the number of items in the FIFO.

Definition at line 261 of file fifo.h.

References cppthread::fifo< T >::f_queue, and cppthread::mutex::lock().

Here is the call graph for this function:

◆ timed_wait() [1/2]

bool cppthread::mutex::timed_wait ( std::uint64_t const  usecs)
inherited

At times it is useful to wait on a mutex to become available without polling the mutex, but only for some time. This function waits for the number of specified micro seconds. The function returns early if the condition was triggered. Otherwise it waits until the specified number of micro seconds elapsed and then returns.

Warning
This function cannot be called if the mutex is not locked or the wait will fail in unpredictable ways.
Exceptions
cppthread_exception_system_errorThis exception is raised if a function returns an unexpected error.
cppthread_exception_mutex_failed_errorThis exception is raised when the mutex wait function fails.
Parameters
[in]usecsThe maximum number of micro seconds to wait until you receive the signal.
Returns
true if the condition was raised, false if the wait timed out.

Definition at line 549 of file mutex.cpp.

References cppthread::mutex::timed_wait().

Referenced by cppthread::fifo< T >::pop_front(), and cppthread::mutex::timed_wait().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ timed_wait() [2/2]

bool cppthread::mutex::timed_wait ( timespec const &  nsecs)
inherited

At times it is useful to wait on a mutex to become available without polling the mutex, but only for some time. This function waits for the number of specified nano seconds. The function returns early if the condition was triggered. Otherwise it waits until the specified number of nano seconds elapsed and then returns.

Warning
This function cannot be called if the mutex is not locked or the wait will fail in unpredictable ways.
Exceptions
cppthread_exception_system_errorThis exception is raised if a function returns an unexpected error.
cppthread_exception_mutex_failed_errorThis exception is raised when the mutex wait function fails.
Parameters
[in]nsecsThe maximum number of nano seconds to wait until you receive the signal.
Returns
true if the condition was raised, false if the wait timed out.
See also
dated_wait(timespec date)

Definition at line 583 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, and cppthread::log.

Here is the call graph for this function:

◆ try_lock()

bool cppthread::mutex::try_lock ( )
inherited

This function tries locking the mutex. If the mutex cannot be locked because another process already locked it, then the function returns immediately with false.

Exceptions
cppthread_exception_invalid_errorIf the lock fails, this exception is raised.
Returns
true if the lock succeeded, false otherwise.

Definition at line 400 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, cppthread::mutex::f_reference_count, and cppthread::log.

Here is the call graph for this function:

◆ unlock()

void cppthread::mutex::unlock ( )
inherited

This function unlock the specified mutex. The function must be called exactly once per call to the lock() function, or successful call to the try_lock() function.

The unlock never waits.

Exceptions
cppthread_exception_invalid_errorIf the unlock fails, this exception is raised.
cppthread_exception_not_locked_errorIf the function is called too many times, then the lock count is going to be zero and this exception will be raised.

Definition at line 443 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, cppthread::mutex::f_reference_count, and cppthread::log.

Referenced by cppthread::guard::is_locked(), cppthread::guard::lock(), and cppthread::guard::unlock().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_item() [1/4]

template<class T >
template<typename C >
cppthread::fifo< T >::validate_item ( C const &  item)
inlineprivate

Validate a fifo item.

This function checks whether the T::valid_workload() function says the item can be processed now or not.

In this case, the class C is not a shared pointer.

Template Parameters
CThe type of the item.
Parameters
[in]itemThe item to verify.
Returns
true if the valid_workload() returns true, false otherwise.

The validate_item() checks whether the item can be returned by the pop_front() function or not.

Definition at line 101 of file fifo.h.

Referenced by cppthread::fifo< T >::byte_size(), and cppthread::fifo< T >::pop_front().

Here is the caller graph for this function:

◆ validate_item() [2/4]

template<class T >
template<typename C >
std::enable_if<!snapdev::is_shared_ptr< C >::value &&!item_has_predicate< C, bool()>::value, bool >::type cppthread::fifo< T >::validate_item ( C const &  item)
inlineprivate

This function always returns true. It is used when the item does not have a valid_workload() function defined.

Template Parameters
CThe type of the item.
Parameters
[in]itemThe item to verify.
Returns
Always true.

Definition at line 120 of file fifo.h.

◆ validate_item() [3/4]

template<class T >
template<typename C >
std::enable_if< snapdev::is_shared_ptr< C >::value &&item_has_predicate< typenameC::element_type, bool()>::value, bool >::type cppthread::fifo< T >::validate_item ( C const &  item)
inlineprivate

This function checks whether the T::valid_workload() function says the item can be processed now or not.

In this case, the class C is a shared pointer to an item T.

Template Parameters
CThe type of the item.
Parameters
[in]itemThe item to verify.
Returns
Always true.

Definition at line 142 of file fifo.h.

◆ validate_item() [4/4]

template<class T >
template<typename C >
std::enable_if< snapdev::is_shared_ptr< C >::value &&!item_has_predicate< typenameC::element_type, bool()>::value, bool >::type cppthread::fifo< T >::validate_item ( C const &  item)
inlineprivate

This function always returns true. It is used when the item is a shared pointer and does not have a valid_workload() function defined.

Template Parameters
CThe type of the item.
Parameters
[in]itemThe item to verify.
Returns
Always true.

Definition at line 161 of file fifo.h.

◆ wait()

void cppthread::mutex::wait ( )
inherited

At times it is useful to wait on a mutex to become available without polling the mutex (which uselessly wastes precious processing time.) This function can be used to wait on a mutex condition.

This version of the wait() blocks until a signal is received.

Warning
This function cannot be called if the mutex is not locked or the wait will fail in unpredictable ways.
Exceptions
cppthread_exception_not_locked_once_errorThis exception is raised if the reference count is not exactly 1. In other words, the mutex must be locked by the caller but only one time.
cppthread_exception_mutex_failed_errorThis exception is raised in the event the conditional wait fails.

Definition at line 494 of file mutex.cpp.

References cppthread::end(), cppthread::mutex::f_impl, and cppthread::log.

Referenced by cppthread::fifo< T >::pop_front(), and cppthread::thread::start().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ f_broadcast

template<class T >
cppthread::fifo< T >::f_broadcast = false
private

This variable is set to true once the done() function called the broadcast() function of the mutex. This way we avoid calling it more than once even if you call the done() function multiple times.

Definition at line 305 of file fifo.h.

Referenced by cppthread::fifo< T >::done(), and cppthread::fifo< T >::pop_front().

◆ f_done

template<class T >
cppthread::fifo< T >::f_done = false
private

This flag tells us whether the FIFO is done or not.

Definition at line 304 of file fifo.h.

Referenced by cppthread::fifo< T >::done(), cppthread::fifo< T >::is_done(), cppthread::fifo< T >::pop_front(), and cppthread::fifo< T >::push_back().

◆ f_impl

cppthread::mutex::f_impl
privateinherited

◆ f_queue

template<class T >
cppthread::fifo< T >::f_queue = items_t()
private

◆ f_reference_count

cppthread::mutex::f_reference_count = 0
privateinherited

The mutex tracks the number of times the mutex gets locked. In the end, the lock reference must be zero for the mutex to be properly destroyed.

Definition at line 84 of file mutex.h.

Referenced by cppthread::mutex::~mutex(), cppthread::mutex::lock(), cppthread::mutex::try_lock(), and cppthread::mutex::unlock().


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

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.