//%2005//////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation, The Open Group. // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // 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 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 // //%///////////////////////////////////////////////////////////////////////////// #ifndef Pegasus_DQueue_h #define Pegasus_DQueue_h #include #include #include PEGASUS_NAMESPACE_BEGIN template class DQueue : public internal_dq { public: static void *operator new(size_t size); static void operator delete(void *dead, size_t size); private: AutoPtr _mutex; //PEP101 AutoPtr _actual_count; DQueue *_dq_next; static DQueue *_headOfFreeList; static const int BLOCK_SIZE; static Mutex _alloc_mut; public: typedef internal_dq Base; DQueue(); DQueue(Boolean head); virtual ~DQueue(); /** @exception IPCException Indicates an IPC error occurred. */ void lock(); /** @exception IPCException Indicates an IPC error occurred. */ void unlock(); /** @exception IPCException Indicates an IPC error occurred. */ void try_lock(); /** @exception IPCException Indicates an IPC error occurred. */ void insert_first_no_lock(L *element); /** @exception IPCException Indicates an IPC error occurred. */ void insert_first(L *element); /** @exception IPCException Indicates an IPC error occurred. */ void insert_last_no_lock(L *element); /** @exception IPCException Indicates an IPC error occurred. */ void insert_last(L *element); /** @exception IPCException Indicates an IPC error occurred. */ void empty_list(); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_first(); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_last(); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_no_lock(const void *key); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_no_lock(const L *key); /** @exception IPCException Indicates an IPC error occurred. */ L *remove(const void *key); /** @exception IPCException Indicates an IPC error occurred. */ L *remove(const L *key); /** @exception IPCException Indicates an IPC error occurred. */ L *reference(const void *key); L *reference(const L *key); /** @exception IPCException Indicates an IPC error occurred. */ L *next(const void * ref); /** @exception IPCException Indicates an IPC error occurred. */ L *prev(const void *ref); /** @exception IPCException Indicates an IPC error occurred. */ Boolean exists(const void *key); /** @exception IPCException Indicates an IPC error occurred. */ Boolean exists(const L *key); Uint32 count(void) { return _actual_count->value() ; } Uint32 size(void) { return _actual_count->value() ; } } ; template class AsyncDQueue: public internal_dq { public: static void * operator new(size_t size); static void operator delete(void *, size_t); private: // asyncdqueue AutoPtr _cond; AutoPtr _slot; AutoPtr _node; AutoPtr _actual_count; AutoPtr _disallow; AutoPtr _capacity; AsyncDQueue *_dq_next; static AsyncDQueue *_headOfFreeList; static const int BLOCK_SIZE; static Mutex _alloc_mut; /** @exception IPCException Indicates an IPC error occurred. */ void _insert_prep(); /** @exception IPCException Indicates an IPC error occurred. */ void _insert_recover(); /** @exception IPCException Indicates an IPC error occurred. */ void _unlink_prep(); /** @exception IPCException Indicates an IPC error occurred. */ void _unlink_recover(); /** @exception IPCException Indicates an IPC error occurred. */ L *_remove_no_lock(const void *key); /** @exception IPCException Indicates an IPC error occurred. */ L *_remove_no_lock(const L *key); public: typedef internal_dq Base; AsyncDQueue() ; AsyncDQueue(Boolean head, Uint32 capacity); virtual ~AsyncDQueue(); void shutdown_queue(); Boolean is_full(); Boolean is_empty(); Boolean is_shutdown(); /** @exception IPCException Indicates an IPC error occurred. */ void try_lock(PEGASUS_THREAD_TYPE myself); /** @exception IPCException Indicates an IPC error occurred. */ void lock(PEGASUS_THREAD_TYPE myself); void unlock(void); /** @exception IPCException Indicates an IPC error occurred. */ void signal_slot(void); /** @exception IPCException Indicates an IPC error occurred. */ void signal_node(); Condition *get_node_cond(); Condition *get_slot_cond(); /** @exception IPCException Indicates an IPC error occurred. */ void wait_for_node(); /** @exception IPCException Indicates an IPC error occurred. */ void set_capacity(Uint32 capacity); Uint32 get_capacity(); /** @exception IPCException Indicates an IPC error occurred. */ void insert_first(L *element); /** @exception IPCException Indicates an IPC error occurred. */ void insert_first_wait(L *element); /** @exception IPCException Indicates an IPC error occurred. */ void insert_last(L *element); /** @exception IPCException Indicates an IPC error occurred. */ void insert_last_wait(L *element); /** @exception IPCException Indicates an IPC error occurred. */ void empty_list(); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_first(); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_first_wait(); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_last(); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_last_wait(); /** @exception IPCException Indicates an IPC error occurred. */ L *remove(const void *key); /** @exception IPCException Indicates an IPC error occurred. */ L *remove(const L *key); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_no_lock(const void *key); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_no_lock(const L *key); /** @exception IPCException Indicates an IPC error occurred. */ L *remove_wait(const void *key); /** @exception IPCException Indicates an IPC error occurred. */ L *next(const L *ref); /** @exception IPCException Indicates an IPC error occurred. */ L *prev(const L *ref); /** @exception IPCException Indicates an IPC error occurred. */ L *reference(const void *key); /** @exception IPCException Indicates an IPC error occurred. */ L *reference(const L *key); Uint32 count(); Uint32 size(); }; template DQueue * DQueue::_headOfFreeList = 0; template const int DQueue::BLOCK_SIZE = 200; template Mutex DQueue::_alloc_mut; template void *DQueue::operator new(size_t size) { if (size != sizeof(DQueue)) return ::operator new(size); AutoMutex autoMut(_alloc_mut); DQueue *p = _headOfFreeList; if(p) _headOfFreeList = p->_dq_next; else { DQueue * newBlock = static_cast *>(::operator new(BLOCK_SIZE * sizeof(DQueue))); int i; for( i = 1; i < BLOCK_SIZE - 1; ++i) newBlock[i]._dq_next = &newBlock[i + 1]; newBlock[BLOCK_SIZE - 1]._dq_next = 0; p = newBlock; _headOfFreeList = &newBlock[1]; } return p; } template void DQueue::operator delete(void *dead, size_t size) { if(dead == 0) return; if(size != sizeof(DQueue)) { ::operator delete(dead); return; } DQueue *p = static_cast *>(dead); AutoMutex autoMut(_alloc_mut); p->_dq_next = _headOfFreeList; _headOfFreeList = p; } template AsyncDQueue * AsyncDQueue::_headOfFreeList =0; template const int AsyncDQueue::BLOCK_SIZE = 20; template Mutex AsyncDQueue::_alloc_mut; template void * AsyncDQueue::operator new(size_t size) { if (size != sizeof(AsyncDQueue)) return ::operator new(size); AutoMutex autoMut(_alloc_mut); AsyncDQueue *p = _headOfFreeList; if(p) _headOfFreeList = p->_dq_next; else { AsyncDQueue * newBlock = static_cast *>(::operator new(BLOCK_SIZE * sizeof(AsyncDQueue))); int i; for( i = 1; i < BLOCK_SIZE - 1; ++i) newBlock[i]._dq_next = &newBlock[i + 1]; newBlock[BLOCK_SIZE - 1]._dq_next = 0; p = newBlock; _headOfFreeList = &newBlock[1]; } return p; } template void AsyncDQueue::operator delete(void *deadObject, size_t size) { if(deadObject == 0) return; if(size != sizeof(AsyncDQueue)) { ::operator delete(deadObject); return; } AsyncDQueue *p = static_cast *>(deadObject); AutoMutex autoMut(_alloc_mut); p->_dq_next = _headOfFreeList; _headOfFreeList = p; } template DQueue::DQueue() : Base(false) { } template DQueue::DQueue(Boolean head) : Base(head) { if(head == true) { _mutex.reset(new Mutex()); _actual_count.reset(new AtomicInt(0)); } } template DQueue::~DQueue() { } template void DQueue::lock() { _mutex->lock(pegasus_thread_self()); } template void DQueue::unlock() { _mutex->unlock(); } template void DQueue::try_lock() { _mutex->try_lock(pegasus_thread_self()); } template void DQueue::insert_first_no_lock(L *element) { if( pegasus_thread_self() != _mutex->get_owner()) throw Permission(pegasus_thread_self()); Base::insert_first(static_cast(element)); (*_actual_count.get())++; } template void DQueue::insert_first(L *element) { if(element == 0) return; AutoMutex autoMut(*_mutex.get()); Base::insert_first(static_cast(element)); (*_actual_count.get())++; } template void DQueue::insert_last_no_lock(L *element) { if( pegasus_thread_self() != _mutex->get_owner()) throw Permission(pegasus_thread_self()); Base::insert_last(static_cast(element)); (*_actual_count.get())++; } template void DQueue::insert_last(L *element) { if(element == 0) return; AutoMutex autoMut(*_mutex.get()); Base::insert_last(static_cast(element)); (*_actual_count.get())++; } template void DQueue::empty_list() { if( Base::count() > 0) { AutoMutex autoMut(*_mutex.get()); Base::empty_list(); (*_actual_count.get()) = 0; } } template L * DQueue::remove_first() { L *ret = 0; if( _actual_count->value() ) { AutoMutex autoMut(*_mutex.get()); ret = static_cast(Base::remove_first()); if( ret != 0 ) (*_actual_count.get())--; } return ret; } template L *DQueue::remove_last() { L * ret = 0; if( _actual_count->value() ) { AutoMutex autoMut(*_mutex.get()); ret = static_cast(Base::remove_last()); if( ret != 0 ) (*_actual_count.get())--; } return ret; } template L *DQueue::remove_no_lock(const void *key) { if(key == 0 ) return 0; if( pegasus_thread_self() != _mutex->get_owner()) throw Permission(pegasus_thread_self()); if (_actual_count->value() ) { L *ret = static_cast(Base::next(0)); while( ret != 0 ) { if (ret->operator==(key)) { ret = static_cast(Base::remove(ret)); if( ret != 0 ) (*_actual_count.get())--; return ret; } ret = static_cast(Base::next(static_cast(ret))); } } return 0 ; } template L * DQueue::remove_no_lock(const L *key) { if(key == 0 ) return 0; if( pegasus_thread_self() != _mutex->get_owner()) throw Permission(pegasus_thread_self()); if (_actual_count->value() ) { L *ret = static_cast(Base::next(0)); while( ret != 0 ) { if (ret->operator==(*key)) { ret = static_cast(Base::remove(static_cast(ret))); if( ret != 0 ) (*_actual_count.get())--; return ret; } ret = static_cast(Base::next(static_cast(ret))); } } return 0 ; } template L * DQueue::remove(const void *key) { L *ret = 0; if( _actual_count->value() > 0 ) { AutoMutex autoMut(*_mutex.get()); ret = DQueue::remove_no_lock(key); } return(ret); } templateL *DQueue::remove(const L *key) { L *ret = 0; if( _actual_count->value() > 0 ) { AutoMutex autoMut(*_mutex.get()); ret = DQueue::remove_no_lock(key); } return(ret); } template L *DQueue::reference(const L *key) { if(key == 0) return 0; if( pegasus_thread_self() != _mutex->get_owner()) throw Permission(pegasus_thread_self()); if( _actual_count->value() ) { L *ret = static_cast(Base::next(0)); while(ret != 0) { if(ret->operator==(*key)) return ret; ret = static_cast(Base::next(static_cast(ret))); } } return(0); } template L *DQueue::reference(const void *key) { if(key == 0) return 0; if( pegasus_thread_self() != _mutex->get_owner()) throw Permission(pegasus_thread_self()); if( _actual_count->value() ) { L *ret = static_cast(Base::next(0)); while(ret != 0) { if(ret->operator==(key)) return ret; ret = static_cast(Base::next(static_cast(ret))); } } return(0); } template L * DQueue::next( const void * ref) { if (_mutex->get_owner() != pegasus_thread_self()) throw Permission(pegasus_thread_self()) ; return static_cast(Base::next(ref)); } template L *DQueue::prev( const void *ref) { if (_mutex->get_owner() != pegasus_thread_self()) throw Permission(pegasus_thread_self()); return static_cast(Base::prev(ref)); } template Boolean DQueue::exists(const void *key) { if(key == 0) return false; Boolean ret = false; if(_actual_count->value() > 0) { AutoMutex autoMut(*_mutex.get()); ret = (DQueue::reference(key) != 0); } return(ret); } template Boolean DQueue::exists(const L *key) { if(key == 0) return false; Boolean ret = false; if(_actual_count->value() > 0) { AutoMutex autoMut(*_mutex.get()); ret = (DQueue::reference(key) != 0); } return(ret); } template void AsyncDQueue::_insert_prep() { if(_disallow->value() > 0) { unlock(); throw ListClosed(); } _slot->lock_object(pegasus_thread_self()); while(true == is_full()) { _slot->unlocked_wait(pegasus_thread_self()); if(_disallow->value() > 0) { unlock(); throw ListClosed(); } } } template void AsyncDQueue::_insert_recover() { _node->unlocked_signal(pegasus_thread_self()); (*_actual_count.get())++; unlock(); } template void AsyncDQueue::_unlink_prep() { if(_disallow->value() > 0) { unlock(); throw ListClosed(); } _node->lock_object(pegasus_thread_self()); while(true == is_empty()) { _node->unlocked_wait(pegasus_thread_self()); if(_disallow->value() > 0) { unlock(); throw ListClosed(); } } } template void AsyncDQueue::_unlink_recover() { _slot->unlocked_signal(pegasus_thread_self()); (*_actual_count.get())--; unlock(); } template L * AsyncDQueue::_remove_no_lock(const void *key) { if(_disallow->value() > 0) { unlock(); throw ListClosed(); } if( pegasus_thread_self() != _cond->get_owner()) throw Permission(pegasus_thread_self()); L *ret = static_cast(Base::next(0)); while(ret != 0) { if(ret->operator==(key)) { return static_cast(Base::remove(static_cast(ret))); } ret = static_cast(Base::next(static_cast(ret))); } return 0; } template L *AsyncDQueue::_remove_no_lock(const L *key) { if(_disallow->value() > 0) { unlock(); throw ListClosed(); } if( pegasus_thread_self() != _cond->get_owner()) throw Permission(pegasus_thread_self()); L *ret = static_cast(Base::next(0)); while(ret != 0) { if(ret->operator==(*key)) { return static_cast(Base::remove(static_cast(ret))); } ret = static_cast(Base::next(static_cast(ret))); } return 0; } template AsyncDQueue::AsyncDQueue() : Base(false) { } template AsyncDQueue::AsyncDQueue(Boolean head, Uint32 capacity) : Base(head) { if(head == true) { _cond.reset(new Mutex()); _slot.reset(new Condition(*_cond.get())); _node.reset(new Condition(*_cond.get())); _actual_count.reset(new AtomicInt(0)); _disallow.reset(new AtomicInt(0)); _capacity.reset(new AtomicInt(capacity)); } } template AsyncDQueue::~AsyncDQueue() { } template void AsyncDQueue::shutdown_queue() { try { lock(pegasus_thread_self()); (*_disallow.get())++; _node->disallow(); _node->unlocked_signal(pegasus_thread_self()); _node->unlocked_signal(pegasus_thread_self()); _slot->disallow(); _slot->unlocked_signal(pegasus_thread_self()); _slot->unlocked_signal(pegasus_thread_self()); unlock(); } catch(const ListClosed &) { (*_disallow.get())++; } } template Boolean AsyncDQueue::is_full() { return false; if( _capacity->value() == 0 ) return false; if(_actual_count->value() >= _capacity->value()) return true; return false; } template Boolean AsyncDQueue::is_empty() { if(_actual_count->value() == 0) return true; return false; } template Boolean AsyncDQueue::is_shutdown() { if( _disallow->value() > 0) return true; return false; } template void AsyncDQueue::try_lock(PEGASUS_THREAD_TYPE myself) { if(_disallow->value() > 0) { throw ListClosed(); } _cond->try_lock(myself); } template void AsyncDQueue::lock(PEGASUS_THREAD_TYPE myself) { if(_disallow->value() > 0) { throw ListClosed(); } _cond->lock(myself); } template void AsyncDQueue::unlock() { _cond->unlock(); } template void AsyncDQueue::signal_slot() { AutoMutex autoMut(*_cond.get()); _slot->unlocked_signal(pegasus_thread_self()); } template void AsyncDQueue::signal_node() { AutoMutex autoMut(*_cond.get()); _node->unlocked_signal(pegasus_thread_self()); } template Condition *AsyncDQueue::get_node_cond() { return _node.get() ; } template Condition * AsyncDQueue::get_slot_cond() { return _slot.get(); } template void AsyncDQueue::wait_for_node() { _unlink_prep(); } template void AsyncDQueue::set_capacity(Uint32 capacity) { lock(pegasus_thread_self()); *_capacity.get() = capacity; unlock(); } template Uint32 AsyncDQueue::get_capacity() { return _capacity->value(); } template void AsyncDQueue::insert_first(L *element) { if(element != 0) { lock(pegasus_thread_self()); if(true == is_full()) { unlock(); throw ListFull(_capacity->value()); } Base::insert_first(static_cast(element)); _insert_recover(); } } template void AsyncDQueue::insert_first_wait(L *element) { if(element != 0) { _insert_prep(); Base::insert_first(static_cast(element)); _insert_recover(); } } template void AsyncDQueue::insert_last(L *element) { if(element != 0) { lock(pegasus_thread_self()); if(true == is_full()) { unlock(); throw ListFull(_capacity->value()); } Base::insert_last(static_cast(element)); _insert_recover(); } } template void AsyncDQueue::insert_last_wait(L *element) { if(element != 0) { _insert_prep(); Base::insert_last(element); _insert_recover(); } } template void AsyncDQueue::empty_list() { lock(pegasus_thread_self()); Base::empty_list(); (*_actual_count.get()) = 0; _slot->unlocked_signal(pegasus_thread_self()); unlock(); } template L *AsyncDQueue::remove_first() { lock(pegasus_thread_self()); L *ret = static_cast(Base::remove_first()); if(ret != 0) { _slot->unlocked_signal(pegasus_thread_self()); (*_actual_count.get())--; } unlock(); return ret; } template L *AsyncDQueue::remove_first_wait() { _unlink_prep(); L *ret = static_cast(Base::remove_first()); _unlink_recover(); return ret; } template L *AsyncDQueue::remove_last() { lock(pegasus_thread_self()); L *ret = static_cast(Base::remove_last()); if(ret != 0) { (*_actual_count.get())--; _slot->unlocked_signal(pegasus_thread_self()); } unlock(); return ret; } template L *AsyncDQueue::remove_last_wait() { _unlink_prep(); L *ret = static_cast(Base::remove_last()); _unlink_recover(); return ret; } template L *AsyncDQueue::remove(const void *key) { if(key == 0) return 0; lock(pegasus_thread_self()); L *ret = _remove_no_lock(key); if(ret != 0) { (*_actual_count.get())--; _slot->unlocked_signal(pegasus_thread_self()); } unlock(); return ret; } templateL *AsyncDQueue::remove(const L *key) { if(key == 0) return 0; lock(pegasus_thread_self()); L *ret = _remove_no_lock(key); if(ret != 0) { (*_actual_count.get())--; _slot->unlocked_signal(pegasus_thread_self()); } unlock(); return ret; } template L *AsyncDQueue::remove_no_lock(const void *key) { if(_disallow->value() > 0) { unlock(); throw ListClosed(); } if(key == 0) return 0; L *ret = 0; if(Base::count() > 0 ) { ret = _remove_no_lock(key); if(ret != 0) { (*_actual_count.get())--; _slot->unlocked_signal(pegasus_thread_self()); } } return ret; } template L *AsyncDQueue::remove_no_lock(const L *key) { if(_disallow->value() > 0) { unlock(); throw ListClosed(); } if(key == 0) return 0; L *ret = 0; if(Base::count() > 0 ) { ret = _remove_no_lock(key); if(ret != 0) { (*_actual_count.get())--; _slot->unlocked_signal(pegasus_thread_self()); } } return ret; } template L *AsyncDQueue::remove_wait(const void *key) { if(key == 0) return 0; lock(pegasus_thread_self()); L *ret = _remove_no_lock(key); while( ret == 0 ) { if(_disallow->value() > 0) { unlock(); throw ListClosed(); } _node->unlocked_wait(pegasus_thread_self()); if(_disallow->value() > 0) { unlock(); throw ListClosed(); } ret = _remove_no_lock(key); } if(ret != 0) { (*_actual_count.get())--; _slot->unlocked_signal(pegasus_thread_self()); } unlock(); return ret; } template L *AsyncDQueue::next(const L *ref) { if( pegasus_thread_self() != _cond->get_owner()) throw Permission(pegasus_thread_self()); return static_cast(Base::next( reinterpret_cast(ref))); } template L *AsyncDQueue::prev(const L *ref) { if( pegasus_thread_self() != _cond->get_owner()) throw Permission(pegasus_thread_self()); return static_cast(Base::prev( reinterpret_cast(ref))); } template L *AsyncDQueue::reference(const void *key) { if(_disallow->value() > 0) { unlock(); throw ListClosed(); } if( key == 0 ) return 0; if( pegasus_thread_self() != _cond->get_owner()) throw Permission(pegasus_thread_self()); if(Base::count() > 0 ) { L *ret = static_cast(Base::next(0)); while(ret != 0) { if(ret->operator==(key)) return ret; ret = static_cast(Base::next(static_cast(ret))); } } return(0); } template L *AsyncDQueue::reference(const L *key) { if(_disallow->value() > 0) { unlock(); throw ListClosed(); } if(key == 0) return 0; if( pegasus_thread_self() != _cond->get_owner()) throw Permission(pegasus_thread_self()); if(Base::count() > 0 ) { L *ret = static_cast(Base::next(0)); while(ret != 0) { if(ret->operator==(*key)) return ret; ret = static_cast(Base::next(static_cast(ret))); } } return(0); } template Uint32 AsyncDQueue::count() { return _actual_count->value(); } template Uint32 AsyncDQueue::size() { return _actual_count->value(); } PEGASUS_NAMESPACE_END #endif /* Pegasus_DQueue_h */