version 1.3, 2006/08/09 21:12:42
|
version 1.9, 2008/12/01 17:49:46
|
|
|
//%2006//////////////////////////////////////////////////////////////////////// |
//%LICENSE//////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// Licensed to The Open Group (TOG) under one or more contributor license |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
// agreements. Refer to the OpenPegasusNOTICE.txt file distributed with |
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; |
// this work for additional information regarding copyright ownership. |
// IBM Corp.; EMC Corporation, The Open Group. |
// Each contributor licenses this file to you under the OpenPegasus Open |
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; |
// Source License; you may not use this file except in compliance with the |
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
// License. |
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
// |
// EMC Corporation; VERITAS Software Corporation; The Open Group. |
// Permission is hereby granted, free of charge, to any person obtaining a |
// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
// copy of this software and associated documentation files (the "Software"), |
// EMC Corporation; Symantec Corporation; The Open Group. |
// to deal in the Software without restriction, including without limitation |
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
// and/or sell copies of the Software, and to permit persons to whom the |
|
// Software is furnished to do so, subject to the following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included |
|
// in all copies or substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
// | // |
// Permission is hereby granted, free of charge, to any person obtaining a copy |
////////////////////////////////////////////////////////////////////////// |
// of this software and associated documentation files (the "Software"), to |
|
// deal in the Software without restriction, including without limitation the |
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|
// sell copies of the Software, and to permit persons to whom the Software is |
|
// furnished to do so, subject to the following conditions: |
|
// |
|
// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN |
|
// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED |
|
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT |
|
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
// |
|
//============================================================================== |
|
// |
|
// Author: Mike Day (mdday@us.ibm.com) |
|
// |
|
// Modified By: Amit K Arora, IBM (amita@in.ibm.com) for PEP#101 |
|
// Alagaraja Ramasubramanian (alags_raj@in.ibm.com) for Bug#1090 |
|
// Amit K Arora, IBM (amita@in.ibm.com) for Bug#2322 |
|
// David Dillard, VERITAS Software Corp. |
|
// (david.dillard@veritas.com) |
|
// Amit K Arora, IBM (amita@in.ibm.com) for Bug#2960 |
|
// |
|
// Reworked By: |
|
// Mike Brasher (m.brasher@inovadevelopment.com) |
|
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
|
|
{ | { |
public: | public: |
| |
/** Constructor (zero means unlimited capacity). |
/** Constructor. |
*/ | */ |
AsyncQueue(size_t capacity = 0); |
AsyncQueue(); |
| |
/** Destructor. | /** Destructor. |
*/ | */ |
virtual ~AsyncQueue(); | virtual ~AsyncQueue(); |
| |
/** Close the queue so that subsequent enqueue() and dequeue() requests |
/** Close the queue. |
result in ListClosed() exceptions. |
|
*/ | */ |
void close(); | void close(); |
| |
/** Enqueue an element at the back of queue. | /** Enqueue an element at the back of queue. |
|
@param element The element to enqueue. |
|
@return True if the element is successfully enqueued, false if the |
|
queue is closed. |
*/ | */ |
void enqueue(ElemType *element); |
Boolean enqueue(ElemType *element); |
|
|
/** Enqueue an element at the back of queue (wait if the queue is full). |
|
*/ |
|
void enqueue_wait(ElemType *element); |
|
| |
/** Dequeue an element from the front of the queue. Return null immediately | /** Dequeue an element from the front of the queue. Return null immediately |
if queue is empty. |
if queue is empty or closed. |
|
@return A pointer to the element that was dequeued, or null if the |
|
queue is empty or closed. |
*/ | */ |
ElemType *dequeue(); | ElemType *dequeue(); |
| |
/** Dequeue an element from the front of the queue (wait if the queue is | /** Dequeue an element from the front of the queue (wait if the queue is |
empty). | empty). |
|
@return A pointer to the element that was dequeued, or null if the |
|
queue is closed (either before or while waiting for an element). |
*/ | */ |
ElemType *dequeue_wait(); | ElemType *dequeue_wait(); |
| |
|
|
| |
/** Return number of element in queue. | /** Return number of element in queue. |
*/ | */ |
Uint32 count() const { return _size.get(); } |
Uint32 count() const { return _rep.size(); } |
|
|
/** Get capacity. |
|
*/ |
|
Uint32 capacity() const { return _capacity.get(); } |
|
|
|
/** Return number of element in queue. |
|
*/ |
|
Uint32 size() const { return _size.get(); } |
|
| |
/** Return true is queue is empty (has zero elements). | /** Return true is queue is empty (has zero elements). |
*/ | */ |
Boolean is_empty() const { return _size.get() == 0; } |
Boolean is_empty() const { return _rep.size() == 0; } |
|
|
/** Return true if the queue is full. |
|
*/ |
|
Boolean is_full() const { return _size.get() == _capacity.get(); } |
|
| |
/** Return true if the queue has been closed (in which case no new | /** Return true if the queue has been closed (in which case no new |
elements may be enqueued). | elements may be enqueued). |
|
|
| |
Mutex _mutex; | Mutex _mutex; |
Condition _not_empty; | Condition _not_empty; |
Condition _not_full; |
|
AtomicInt _capacity; |
|
AtomicInt _size; |
|
AtomicInt _closed; | AtomicInt _closed; |
typedef List<ElemType,NullLock> Rep; | typedef List<ElemType,NullLock> Rep; |
Rep _rep; | Rep _rep; |
}; | }; |
| |
template<class ElemType> | template<class ElemType> |
AsyncQueue<ElemType>::AsyncQueue(size_t capacity) : _capacity(capacity) |
AsyncQueue<ElemType>::AsyncQueue() : |
|
_mutex(Mutex::NON_RECURSIVE) |
{ | { |
if (capacity == 0) |
|
_capacity.set(0x7FFFFFFF); |
|
} | } |
| |
template<class ElemType> | template<class ElemType> |
|
|
if (!is_closed()) | if (!is_closed()) |
{ | { |
_closed++; | _closed++; |
_not_full.signal(); |
|
_not_empty.signal(); | _not_empty.signal(); |
} | } |
} | } |
| |
template<class ElemType> | template<class ElemType> |
void AsyncQueue<ElemType>::enqueue(ElemType *element) |
Boolean AsyncQueue<ElemType>::enqueue(ElemType *element) |
{ | { |
if (element) | if (element) |
{ | { |
AutoMutex auto_mutex(_mutex); | AutoMutex auto_mutex(_mutex); |
| |
if (is_closed()) | if (is_closed()) |
throw ListClosed(); |
|
|
|
if (is_full()) |
|
throw ListFull(_capacity.get()); |
|
|
|
_rep.insert_back(element); |
|
_size++; |
|
_not_empty.signal(); |
|
} |
|
} |
|
|
|
template<class ElemType> |
|
void AsyncQueue<ElemType>::enqueue_wait(ElemType *element) |
|
{ |
|
if (element) |
|
{ |
|
AutoMutex auto_mutex(_mutex); |
|
|
|
while (is_full()) |
|
{ | { |
if (is_closed()) |
return false; |
throw ListClosed(); |
|
|
|
_not_full.wait(_mutex); |
|
} | } |
| |
if (is_closed()) |
|
throw ListClosed(); |
|
|
|
_rep.insert_back(element); | _rep.insert_back(element); |
_size++; |
|
_not_empty.signal(); | _not_empty.signal(); |
} | } |
|
|
|
return true; |
} | } |
| |
template<class ElemType> | template<class ElemType> |
|
|
{ | { |
AutoMutex auto_mutex(_mutex); | AutoMutex auto_mutex(_mutex); |
_rep.clear(); | _rep.clear(); |
_size = 0; |
|
_not_full.signal(); |
|
} | } |
| |
template<class ElemType> | template<class ElemType> |
|
|
AutoMutex auto_mutex(_mutex); | AutoMutex auto_mutex(_mutex); |
| |
if (is_closed()) | if (is_closed()) |
throw ListClosed(); |
|
|
|
ElemType* p = _rep.remove_front(); |
|
|
|
if (p) |
|
{ | { |
_size--; |
return 0; |
_not_full.signal(); |
|
} | } |
| |
return p; |
return _rep.remove_front(); |
} | } |
| |
template<class ElemType> | template<class ElemType> |
|
|
while (is_empty()) | while (is_empty()) |
{ | { |
if (is_closed()) | if (is_closed()) |
throw ListClosed(); |
{ |
|
return 0; |
|
} |
| |
_not_empty.wait(_mutex); | _not_empty.wait(_mutex); |
} | } |
| |
if (is_closed()) | if (is_closed()) |
throw ListClosed(); |
{ |
|
return 0; |
|
} |
| |
ElemType* p = _rep.remove_front(); | ElemType* p = _rep.remove_front(); |
PEGASUS_DEBUG_ASSERT(p != 0); | PEGASUS_DEBUG_ASSERT(p != 0); |
_size--; |
|
_not_full.signal(); |
|
| |
return p; | return p; |
} | } |