#include <distributionQueue.h>
Inheritance diagram for dlr::thread::DistributionQueue< Type >:


Public Types | |
| typedef ClientID< Type > | ClientID |
| Each thread that interacts with a particular DistributionQueue instance must create a ClientID instance, and then register with the DistributionQueue by calling the registerClient() member function of that DistributionQueue instance, passing the clientID instance as an argument. | |
Public Member Functions | |
| DistributionQueue (size_t maximumLength, size_t numberOfClients=2) | |
| This constructor specifies the maximum length of the FIFO. | |
| DistributionQueue (const DistributionQueue< Type > &source) | |
| The copy constructor does a shallow copy. | |
| virtual | ~DistributionQueue () |
| Destroys the DistributionQueue instance and releases any resources. | |
| DistributionQueue< Type > & | operator= (const DistributionQueue< Type > &source) |
| The assignment operator does a shallow copy. | |
| void | bufferBack (const ClientID &clientID) |
| This member function copies the tail element of the DistributionQueue into an interal buffer, and then removes it from the queue so that other threads can no longer access it. | |
| bool | bufferBack (const ClientID &clientID, double timeout) |
| This member function copies the tail element of the DistributionQueue into an interal buffer, and then removes it from the queue so that other threads can no longer access it. | |
| void | clear () |
| This member function empties the queue. | |
| void | copyBuffer (const ClientID &clientID, Type &target) |
| This member function copies the buffered element (see member function bufferBack() from the internal buffer into user code. | |
| size_t | getMaximumLength () |
| This member function returns the length at which the DistributionQueue instance will stop accepting new elements. | |
| void | lockBack (const ClientID &clientID) |
| This member function locks the DistributionQueue instance so that items cannot be pushed or removed by other threads. | |
| bool | lockBack (const ClientID &clientID, double timeout) |
| This member function locks the DistributionQueue instance so that items cannot be pushed or removed by other threads. | |
| void | pushFront (const ClientID &clientID, const Type &element) |
| This member function is called by producer threads to add elements to the head of the queue. | |
| void | registerClient (ClientID &clientID, const std::string &clientName="anonymous") |
| This member function introduces a thread to a DistributionQueue instance. | |
| void | unlockBack (const ClientID &clientID) |
| This member function releases a lock acquired by lockBack(). | |
| void | makeCopyable (bool copyableFlag=true) |
| This member function enables (or disables) copying of the Monitor instance. | |
Protected Member Functions | |
| void | copyOther (const Monitor &other) |
| This protected member function is called by the copy constructor and assignment operator in order to copy another Monitor instance in a thread-safe way. | |
| Condition | createCondition (bool doInitialize=true) |
| This protected member function creates a condition to be used for communicating with other threads. | |
| Token | getToken () |
| This protected member function requests, and waits for, a virtual "token" which is shared between threads. | |
| Token | getToken (double timeout) |
| This protected member function requests, and waits for, a virtual "token" which is shared between threads. | |
| void | releaseResources () |
| This protected member function is called by the destructor and assignment operator to decrement reference counts, etc. | |
| void | signalOne (Condition &condition) |
| This protected member function wakes up one of the threads which is waiting on the specified condition. | |
| void | signalAll (Condition &condition) |
| This protected member function wakes up all of the threads which are waiting on the specified condition. | |
| void | wait (Condition &condition, Token &token) |
| This protected member function waits until signalOne() or signalAll() is called by another thread with the same Condition as its argument. | |
| bool | wait (Condition &condition, Token &token, double timeout) |
| This protected member function waits until signalOne() or signalAll() is called by another thread with the same Condition as its argument. | |
If you want each item on the queue to be consumed once by each consumer thread, you should use a BroacastQueue instead of a DistributionQueue.
Create the DistributionQueue instance before instantiating the producer and consumer threads, and provide each thread with a copy of, pointer to, or reference to the DistributionQueue. Producers can stuff the FIFO by the pushFront() member function. Consumers can extract data from the other end using the bufferBack() and getBuffer() member functions. The bufferBack()/getBuffer() combination is used instead of the more traditional copyBack()/popBack() interface in order to allow an interface which is both thread-safe and exception-safe. Note that a careful analysis of exception safety has not been done. The interface was selected so as not to preclude exception safety.
During normal usage all client threads are expected to stay within maximumLength elements of the head. If a consumer thread falls more than maximumLength elements behind the head, then the next call to push_back() will throw an overflow exception. This behavior may change in the future.
Definition at line 57 of file distributionQueue.h.
| typedef ClientID<Type> dlr::thread::DistributionQueue< Type >::ClientID |
Each thread that interacts with a particular DistributionQueue instance must create a ClientID instance, and then register with the DistributionQueue by calling the registerClient() member function of that DistributionQueue instance, passing the clientID instance as an argument.
The same ClientID instance must be passed as an argument in subsequent interactions with that DistributionQueue instance. The ClientID instance identifies the thread to the DistributionQueue, and simplifies internal bookkeeping.
Definition at line 73 of file distributionQueue.h.
| dlr::thread::DistributionQueue< Type >::DistributionQueue | ( | size_t | maximumLength, | |
| size_t | numberOfClients = 2 | |||
| ) | [inline] |
This constructor specifies the maximum length of the FIFO.
| maximumLength | This argument specifies the maximum length of the FIFO. All consumers are expected to call this->popBack() frequently enough to stay within this many elements of the head of the FIFO. If consumers fail to keep up, then calls to pushFront(), bufferBack() or lockBack() may throw exceptions. | |
| numberOfClients | This argument can be used to specify the number of threads that will interact with the DistributionQueue instance. If this argument is not provided, the DistributionQueue will function normally, except that memory usage will likely be higher, and execution time for some member function calls may be increased. |
Definition at line 398 of file distributionQueue.h.
References DLR_THROW, and dlr::thread::Monitor::makeCopyable().
| dlr::thread::DistributionQueue< Type >::DistributionQueue | ( | const DistributionQueue< Type > & | source | ) | [inline] |
The copy constructor does a shallow copy.
Operating on the copy has exactly the same effect as operating on the original.
| source | The DistributionQueue instance to be copied. |
Definition at line 438 of file distributionQueue.h.
References dlr::thread::Monitor::getToken(), dlr::thread::DistributionQueue< Type >::m_bufferArrayPtr, dlr::thread::DistributionQueue< Type >::m_clientNameMapPtr, dlr::thread::DistributionQueue< Type >::m_dataArray, dlr::thread::DistributionQueue< Type >::m_headChangedCondition, dlr::thread::DistributionQueue< Type >::m_headIndexPtr, dlr::thread::DistributionQueue< Type >::m_isLockedCondition, dlr::thread::DistributionQueue< Type >::m_isLockedPtr, dlr::thread::DistributionQueue< Type >::m_maxNumberOfClientsPtr, dlr::thread::DistributionQueue< Type >::m_numberOfClientsPtr, dlr::thread::DistributionQueue< Type >::m_referenceCountPtr, dlr::thread::DistributionQueue< Type >::m_size, and dlr::thread::DistributionQueue< Type >::m_tailIndexPtr.
| dlr::thread::DistributionQueue< Type >::~DistributionQueue | ( | ) | [inline, virtual] |
Destroys the DistributionQueue instance and releases any resources.
Definition at line 476 of file distributionQueue.h.
References dlr::thread::Monitor::getToken().
| DistributionQueue< Type > & dlr::thread::DistributionQueue< Type >::operator= | ( | const DistributionQueue< Type > & | source | ) | [inline] |
The assignment operator does a shallow copy.
After assignment, operating on the copy has exactly the same effect as operating on the original.
| source | The DistributionQueue instance to be copied. |
Definition at line 503 of file distributionQueue.h.
References dlr::thread::Monitor::copyOther(), dlr::thread::Monitor::getToken(), and dlr::thread::Monitor::operator=().
| void dlr::thread::DistributionQueue< Type >::bufferBack | ( | const ClientID & | clientID | ) | [inline] |
This member function copies the tail element of the DistributionQueue into an interal buffer, and then removes it from the queue so that other threads can no longer access it.
Repeated calls to bufferBack() will copy and remove subsequent elements from the queue.
Each thread has its own buffer, so elements can be buffered by two or more consumer threads with no conflict.
If all items have been removed from the queue, bufferBack() will block, waiting for a new element to be copied onto the queue.
| clientID | This argument identifies the calling thread to the DistributionQueue. It should have been previously registered with the DistributionQueue by calling member function registerClient(). |
Definition at line 523 of file distributionQueue.h.
References dlr::thread::DistributionQueue< Type >::lockBack(), dlr::thread::ClientID< Type >::m_idNumber, and dlr::thread::DistributionQueue< Type >::unlockBack().
| bool dlr::thread::DistributionQueue< Type >::bufferBack | ( | const ClientID & | clientID, | |
| double | timeout | |||
| ) | [inline] |
This member function copies the tail element of the DistributionQueue into an interal buffer, and then removes it from the queue so that other threads can no longer access it.
It is just like void bufferBack(const ClientID&), with the exception that it will not block for longer than the specified timeout.
| clientID | This argument identifies the calling thread to the DistributionQueue. It should have been previously registered with the DistributionQueue by calling member function registerClient(). | |
| timeout | This argument specifies the total amount of time that bufferBack is permitted to block while waiting for access to the queue and/or waiting for a new element to become available. If timeout is less than or equal to zero then the call will return immediately. |
Definition at line 550 of file distributionQueue.h.
References dlr::thread::ClientID< Type >::m_idNumber, and dlr::thread::DistributionQueue< Type >::unlockBack().
| void dlr::thread::DistributionQueue< Type >::clear | ( | ) | [inline] |
This member function empties the queue.
Definition at line 579 of file distributionQueue.h.
References dlr::thread::Monitor::getToken().
| void dlr::thread::DistributionQueue< Type >::copyBuffer | ( | const ClientID & | clientID, | |
| Type & | target | |||
| ) | [inline] |
This member function copies the buffered element (see member function bufferBack() from the internal buffer into user code.
Repeated calls to copyBuffer() will copy the same element until a new call to bufferBack() is made. If copyBuffer() is called before any calls to bufferBack() are made, a LogicException will be thrown.
| clientID | This argument identifies the calling thread to the DistributionQueue. It should have been previously registered with the DistributionQueue by calling member function registerClient(). | |
| target | This reference argument is used to return a copy of the tail element in the queue. |
Definition at line 594 of file distributionQueue.h.
References dlr::thread::ClientID< Type >::m_idNumber.
| size_t dlr::thread::DistributionQueue< Type >::getMaximumLength | ( | ) | [inline] |
This member function returns the length at which the DistributionQueue instance will stop accepting new elements.
Definition at line 207 of file distributionQueue.h.
| void dlr::thread::DistributionQueue< Type >::lockBack | ( | const ClientID & | clientID | ) | [inline] |
This member function locks the DistributionQueue instance so that items cannot be pushed or removed by other threads.
By never using this member function, you will avoid many headaches, so please use copyBack() instead if at all possible. Member function lockBack() is provided to handle a few extreme circumstances.
Member function lockBack() will block until the lock is acquired. If the queue is empty, lockBack() will sleep until data is available, and then block until the lock is acquired.
An example of a circumstance in which it makes sense to use lockBack() is when the distributionQueue elements contain pointers or references to data, so that copyBuffer() gives you a copy of a pointer, but doesn't actually copy the data. Presumably, the producer threads are smart enough not to de-allocate the data until the element drops of the end of the queue, so you can be confident that you're getting a good pointer at the time of the bufferBack() call, but there's nothing to stop the associated data from being de-allocated) after the call, when the consumer is still trying to access it. In this case, it makes sense to call lockBack() in the following sequence.
myDistributionQueue.lockBack(myClientID);
myDistributionQueue.bufferBack(myClientID);
myDistributionQueue.copyBuffer(myClientID, myLocalElement);
// Code here does accesses to the referenced data.
myDistributionQueue.unlockBack(myClientID);
Member function bufferBack() is smart enough not to deadlock when copying an already-locked element.
| clientID | This argument identifies the calling thread to the DistributionQueue. It should have been previously registered with the DistributionQueue by calling member function registerClient(). |
Definition at line 605 of file distributionQueue.h.
References dlr::thread::Monitor::getToken(), and dlr::thread::Monitor::wait().
Referenced by dlr::thread::DistributionQueue< Type >::bufferBack().
| bool dlr::thread::DistributionQueue< Type >::lockBack | ( | const ClientID & | clientID, | |
| double | timeout | |||
| ) | [inline] |
This member function locks the DistributionQueue instance so that items cannot be pushed or removed by other threads.
By never using this member function, you will avoid many headaches. It is just like void lockBack(const ClientID&), with the exception that it will not block for longer than the specified timeout.
| clientID | This argument identifies the calling thread to the DistributionQueue. It should have been previously registered with the DistributionQueue by calling member function registerClient(). | |
| timeout | This argument controls how long the call to lockBack() will block waiting for the lock to become available. If timeout is less than or equal to zero, then the call to will return immediately. |
Definition at line 629 of file distributionQueue.h.
References dlr::portability::getCurrentTime(), and dlr::thread::Monitor::getToken().
| void dlr::thread::DistributionQueue< Type >::pushFront | ( | const ClientID & | clientID, | |
| const Type & | element | |||
| ) | [inline] |
This member function is called by producer threads to add elements to the head of the queue.
When the element is added to the queue, it is copied, not referenced.
| clientID | This argument identifies the calling thread to the DistributionQueue. It should have been previously registered with the DistributionQueue by calling member function registerClient(). | |
| element | This argument is the element to be copied onto the head of the DistributionQueue instance. |
Definition at line 663 of file distributionQueue.h.
References DLR_THROW, dlr::thread::Monitor::getToken(), dlr::thread::ClientID< Type >::m_idNumber, and dlr::thread::Monitor::signalAll().
| void dlr::thread::DistributionQueue< Type >::registerClient | ( | ClientID & | clientID, | |
| const std::string & | clientName = "anonymous" | |||
| ) | [inline] |
This member function introduces a thread to a DistributionQueue instance.
The thread should create a ClientID instance, and then call registerClient() exactly once, passing the ClientID instance as the first argument. This same ClientID instance should be used by the calling thread in subsequent interactions with the DistributionQueue instance. Using the same ClientID instance to interact with another DistributionQueue instance (besides *this) is bad, and will have undefined results.
Note that the ClientID class is currently not copyable. This means the client thread should create the ClientID in an outer scope and then pass it by reference into any inner scopes that need access to the DistributionQueue.
| clientID | This argument is the clientID that will be used to identify the calling thread to the DistributionQueue in future interactions. | |
| clientName | This argument specifies a name for the thread. It is useful to specify a unique name for each thread that interacts with a DistributionQueue instance because this will make it easier to debug any exceptions thrown by the DistributionQueue member functions. |
Definition at line 716 of file distributionQueue.h.
References dlr::thread::Monitor::getToken(), dlr::thread::ClientID< Type >::m_count, dlr::thread::ClientID< Type >::m_idNumber, and dlr::thread::ClientID< Type >::m_index.
| void dlr::thread::DistributionQueue< Type >::unlockBack | ( | const ClientID & | clientID | ) | [inline] |
This member function releases a lock acquired by lockBack().
| clientID | This argument identifies the calling thread to the DistributionQueue. It should have been previously registered with the DistributionQueue by calling member function registerClient(). |
Definition at line 756 of file distributionQueue.h.
References dlr::thread::Monitor::getToken().
Referenced by dlr::thread::DistributionQueue< Type >::bufferBack().
| void dlr::thread::Monitor::makeCopyable | ( | bool | copyableFlag = true |
) | [inline, inherited] |
This member function enables (or disables) copying of the Monitor instance.
| copyableFlag | When this argument is left at its default value of true, a call to makeCopyable will enable copying of the Monitor instance. Explicitly setting this argument to false will reverse the effect of makeCopyable() and disable copying. |
Definition at line 238 of file monitor.h.
Referenced by dlr::thread::DistributionQueue< Type >::DistributionQueue().
| void dlr::thread::Monitor::copyOther | ( | const Monitor & | other | ) | [protected, inherited] |
This protected member function is called by the copy constructor and assignment operator in order to copy another Monitor instance in a thread-safe way.
| other | This argument is the Monitor instance to be copied. |
Definition at line 282 of file monitor.cpp.
References DLR_THROW, dlr::thread::Monitor::getToken(), dlr::thread::Monitor::m_boostConditionVectorPtr, dlr::thread::Monitor::m_isCopyable, dlr::thread::Monitor::m_referenceCountPtr, and dlr::thread::Monitor::m_tokenMutexPtr.
Referenced by dlr::thread::Monitor::Monitor(), dlr::thread::Monitor::operator=(), and dlr::thread::DistributionQueue< Type >::operator=().
| Condition dlr::thread::Monitor::createCondition | ( | bool | doInitialize = true |
) | [protected, inherited] |
This protected member function creates a condition to be used for communicating with other threads.
If argument doInitialize is true, then the resources allocated by createCondition() are not returned to the system until the Monitor instance is destroyed.
Special care must be taken when creating Condition objects in copy constructors. The member initialization list of the copy constructor should create a dummy condition by setting argument doInitialize to false, and the copying of the condition from the to-be-copied Monitor instance should be done in the body of the copy constructor, where it can be protected by creation of a Token instance. Please refer to the class documentation for Monitor to see an example.
| doInitialize | This parameter should be set to false in the parameter initializion lists of copy constructors in order to suppress allocation of resources. Note(xxx): is this really necessary now that condition has no reference count? |
Definition at line 306 of file monitor.cpp.
References dlr::thread::Monitor::getToken().
| Token dlr::thread::Monitor::getToken | ( | ) | [inline, protected, inherited] |
This protected member function requests, and waits for, a virtual "token" which is shared between threads.
The caller will block until the it gets the token, at which point all other callers will block until the token goes out-of-scope in the callers thread.
Definition at line 292 of file monitor.h.
Referenced by dlr::thread::DistributionQueue< Type >::clear(), dlr::thread::Monitor::copyOther(), dlr::thread::Monitor::createCondition(), dlr::thread::DistributionQueue< Type >::DistributionQueue(), dlr::thread::DistributionQueue< Type >::lockBack(), dlr::thread::DistributionQueue< Type >::operator=(), dlr::thread::DistributionQueue< Type >::pushFront(), dlr::thread::DistributionQueue< Type >::registerClient(), dlr::thread::Monitor::releaseResources(), dlr::thread::DistributionQueue< Type >::unlockBack(), and dlr::thread::DistributionQueue< Type >::~DistributionQueue().
| Token dlr::thread::Monitor::getToken | ( | double | timeout | ) | [inline, protected, inherited] |
This protected member function requests, and waits for, a virtual "token" which is shared between threads.
It is just like getToken(), with the exception that it will not block for longer than the specified timeout. If the timout expires before the token is acquired, a TimeoutException is thrown.
| void dlr::thread::Monitor::releaseResources | ( | ) | [protected, inherited] |
This protected member function is called by the destructor and assignment operator to decrement reference counts, etc.
Definition at line 325 of file monitor.cpp.
References dlr::thread::Monitor::getToken().
Referenced by dlr::thread::Monitor::operator=(), and dlr::thread::Monitor::~Monitor().
| void dlr::thread::Monitor::signalOne | ( | Condition & | condition | ) | [inline, protected, inherited] |
This protected member function wakes up one of the threads which is waiting on the specified condition.
If no thread is waiting, then signalOne() does nothing. The awakened thread will become active after the current thread releases the token. Note that this behavior is different from the behavior of signal() in Hoare's paper: in Hoare's formulation, the awakened thread becomes active immediately, and control returns to the current thread after the awakened thread releases the token. This difference is immaterial if you follow the usual convention of only calling signalOne() as the last line of a member function.
| condition | This argument is the condition to signal. |
Definition at line 332 of file monitor.h.
References dlr::thread::Condition::signalOne().
| void dlr::thread::Monitor::signalAll | ( | Condition & | condition | ) | [inline, protected, inherited] |
This protected member function wakes up all of the threads which are waiting on the specified condition.
If no thread is waiting, then signalAll() does nothing. The awakened threads will become active (each in turn) after the current thread releases the token. Note that signalAll() has no analog in Hoare's paper.
| condition | This argument is the condition to signal. |
Definition at line 346 of file monitor.h.
References dlr::thread::Condition::signalAll().
Referenced by dlr::thread::DistributionQueue< Type >::pushFront().
| void dlr::thread::Monitor::wait | ( | Condition & | condition, | |
| Token & | token | |||
| ) | [inline, protected, inherited] |
This protected member function waits until signalOne() or signalAll() is called by another thread with the same Condition as its argument.
| condition | This argument is the condition on which to wait. | |
| token | This argument is a token instance, which should have been acquired using getToken() at the beginning of the member function which is now calling wait(). |
Definition at line 363 of file monitor.h.
References dlr::thread::Condition::wait().
Referenced by dlr::thread::DistributionQueue< Type >::lockBack().
| bool dlr::thread::Monitor::wait | ( | Condition & | condition, | |
| Token & | token, | |||
| double | timeout | |||
| ) | [inline, protected, inherited] |
This protected member function waits until signalOne() or signalAll() is called by another thread with the same Condition as its argument.
It is just like wait(Condition&), with the exception that it will not block for longer than the specified timeout.
| condition | This argument is the condition on which to wait. | |
| token | This argument is a token instance, which should have been acquired using getToken() at the beginning of the member function which is now calling wait(). | |
| timeout | This argument specifies how long to wait for the condition to be satisfied. |
Definition at line 387 of file monitor.h.
References dlr::thread::Condition::wait().
1.5.2