DualQueue Class Reference

#include <coherence/util/DualQueue.hpp>

Inherits AbstractConcurrentQueue.

List of all members.


Detailed Description

The DualQueue is optimized for the producer consumer use case.

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 seperate lists, and protected by seperate locks.

When a consumer looks at the head of the queue, if it is empty, the head and tail will be swaped.

Author:
nsa 2008.02.13

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.

Parameters:
oh element to be appended to this Queue
Returns:
true if the collection changed as a result of this call
Exceptions:
ClassCastException if the class of the specified element prevents it from being added to this Queue

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.

Parameters:
oh element ot be prepended to this Queue
Returns:
true if the collection changed as a result of this call
Exceptions:
ClassCastException if the class of the specified element prevents it from being added to this Queue

virtual bool isEmpty () const
 Determine whether the Queue is empty or not.

Returns:
true if the Queue is empty; false if 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.

Returns:
the first element in the front of this Queue or null if the Queue is empty

virtual Object::Holder removeNoWait ()
 Removes and returns the first element from the front of this Queue.

The blocking equivalent of this method is "remove".

Returns:
the first element in the front of this Queue or NULL if the Queue is empty


Protected Member Functions

 DualQueue ()
 Create a new DaulQueue.
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.
virtual void setHeadLock (Object::Handle oh)
 Set the head lock.

Protected Attributes

MemberHandle< Listm_hElementList
 The List that backs the queue.
MemberHandle< Listm_hHeadElementList
 The storage for the head of the queue.
MemberHandle< Objectm_hHeadLock
 Lock protecting operations on the head of the queue, and tail swapping.

Constructor & Destructor Documentation

DualQueue (  )  [protected]

Create a new DaulQueue.

Returns:
a new DualQueu


Member Function Documentation

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.

Returns:
true iff the head and tail were swapped

virtual List::Handle getHeadElementList (  )  [protected, virtual]

Return the head element list.

Returns:
the head element list

virtual void setHeadElementList ( List::Handle  hList  )  [protected, virtual]

Set the head element list.

Parameters:
hList the new head list to set

virtual List::Handle getElementList (  )  [protected, virtual]

Return the element list (tail).

Returns:
the element list

virtual void setElementList ( List::Handle  hList  )  [protected, virtual]

Set the element list (tail).

Parameters:
hList the new list to set

virtual Object::Handle getHeadLock (  )  [protected, virtual]

Return the head lock.

Returns:
the head lock

virtual void setHeadLock ( Object::Handle  oh  )  [protected, virtual]

Set the head lock.

Parameters:
oh the new lock to use as the headlock


Member Data Documentation

MemberHandle<List> m_hElementList [protected]

The List that backs the queue.

For a dual queue the ElementList is the tail.

MemberHandle<Object> m_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 appraoch was chosen as it allows users of the DualQueue to perform external synchronization without risking deadlock.


The documentation for this class was generated from the following file: Copyright (c) 2000-2008 Oracle. All rights reserved.