#include <coherence/util/DualQueue.hpp>
Inherits AbstractConcurrentQueue.
Producers work on the tail of the queue, consumers operate on the head of the queue. The two portions of the queue are maintained as separate lists, and protected by separate locks.
When a consumer looks at the head of the queue, if it is empty, the head and tail will be swapped.
Public Types | |||||||
typedef spec::Handle | Handle | ||||||
DualQueue Handle definition. | |||||||
typedef spec::View | View | ||||||
DualQueue View definition. | |||||||
typedef spec::Holder | Holder | ||||||
DualQueue Holder definition. | |||||||
Public Member Functions | |||||||
virtual bool | add (Object::Holder oh) | ||||||
Appends the specified element to the end of this queue. Queues may place limitations on what types of elements may be added and should clearly specify in their documentation any restrictions.
| |||||||
virtual bool | addHead (Object::Holder oh) | ||||||
Insert the specified element to the front of this queue. Queues may place limitations on what types of elements may be added and should clearly specify in their documentation any restrictions.
| |||||||
virtual bool | isEmpty () const | ||||||
Determine whether the Queue is empty or not.
| |||||||
virtual Object::Holder | peekNoWait () | ||||||
Returns the first element from the front of this Queue. There is no blocking equivalent of this method as it would require notification to wake up from an empty Queue, and this would mean that the "add" and "addHead" methods would need to perform notifyAll over notify which has performance implications.
| |||||||
virtual Object::Holder | removeNoWait () | ||||||
Removes and returns the first element from the front of this Queue. The blocking equivalent of this method is "remove".
| |||||||
Protected Member Functions | |||||||
DualQueue () | |||||||
Create a new DualQueue. | |||||||
virtual bool | swapNoWait () | ||||||
Swap the head and the tail, but only if the head is empty and the tail is not. | |||||||
virtual List::Handle | getHeadElementList () | ||||||
Return the head element list. | |||||||
virtual void | setHeadElementList (List::Handle hList) | ||||||
Set the head element list. | |||||||
virtual List::Handle | getElementList () | ||||||
Return the element list (tail). | |||||||
virtual void | setElementList (List::Handle hList) | ||||||
Set the element list (tail). | |||||||
virtual Object::Handle | getHeadLock () | ||||||
Return the head lock. | |||||||
Protected Attributes | |||||||
FinalHandle< Object > | f_hHeadLock | ||||||
Lock protecting operations on the head of the queue, and tail swapping. | |||||||
MemberHandle< List > | m_hElementList | ||||||
The List that backs the queue. | |||||||
MemberHandle< List > | m_hHeadElementList | ||||||
The storage for the head of the queue. |
virtual bool swapNoWait | ( | ) | [protected, virtual] |
Swap the head and the tail, but only if the head is empty and the tail is not.
The calling thread must already hold a the head lock.
virtual List::Handle getHeadElementList | ( | ) | [protected, virtual] |
Return the head element list.
virtual void setHeadElementList | ( | List::Handle | hList | ) | [protected, virtual] |
virtual List::Handle getElementList | ( | ) | [protected, virtual] |
Return the element list (tail).
virtual void setElementList | ( | List::Handle | hList | ) | [protected, virtual] |
virtual Object::Handle getHeadLock | ( | ) | [protected, virtual] |
Return the head lock.
FinalHandle<Object> f_hHeadLock [protected] |
Lock protecting operations on the head of the queue, and tail swapping.
We cannot simply lock on the head element list as it gets swapped with the tail.
To avoid deadlock issues the Queue lock should never be obtained while holding the head lock.
For example:
COH_SYNCHRONIZED(getHeadLock()) { COH_SYNCHRONIZED(this) { // this is NOT ok } } COH_SYNCHRONIZED(this) { COH_SYNCHRONIZED(getHeadLock()) { // this is ok } }
The latter approach was chosen as it allows users of the DualQueue to perform external synchronization without risking deadlock.
MemberHandle<List> m_hElementList [protected] |
The List that backs the queue.
For a dual queue the ElementList is the tail.