#ifndef __SHM_QUEUE_H__ #define __SHM_QUEUE_H__ #include "usg_common.h" #include "hashtable.h" #include "lock_free_queue.h" #include "logger_factory.h" #include "shm_allocator.h" #include "sem_util.h" // default Queue size // #define LOCK_FREE_Q_DEFAULT_SIZE 16 template < typename ELEM_T> class SHMQueue { private: const int KEY; public: /// @brief constructor of the class SHMQueue(int key=0, size_t qsize = LOCK_FREE_Q_DEFAULT_SIZE); ~SHMQueue(); inline uint32_t size(); inline bool full(); inline bool empty(); inline bool push(const ELEM_T &a_data); inline bool push_nowait(const ELEM_T &a_data); inline bool push_timeout(const ELEM_T &a_data, struct timespec * timeout); inline bool pop(ELEM_T &a_data); inline bool pop_nowait(ELEM_T &a_data); inline bool pop_timeout(ELEM_T &a_data, struct timespec * timeout); inline ELEM_T& operator[](unsigned i); static void remove_queues_exclude(int *keys, size_t length); private: protected: /// @brief the actual queue-> methods are forwarded into the real /// implementation LockFreeQueue* queue; private: /// @brief disable copy constructor declaring it private SHMQueue(const SHMQueue &a_src); }; template < typename ELEM_T > void SHMQueue::remove_queues_exclude(int *keys, size_t length) { hashtable_t *hashtable = mm_get_hashtable(); std::set* keyset = hashtable_keyset(hashtable); std::set::iterator keyItr; LockFreeQueue* mqueue; bool found; for (keyItr = keyset->begin(); keyItr != keyset->end(); keyItr++) { found = false; for(size_t i = 0; i < length; i++) { if(*keyItr == keys[i]) { found = true; break; } } if(!found) { mqueue = (LockFreeQueue *)hashtable_get(hashtable, *keyItr); delete mqueue; } } delete keyset; } template < typename ELEM_T > SHMQueue::SHMQueue(int key, size_t qsize): KEY(key) { hashtable_t *hashtable = mm_get_hashtable(); queue = (LockFreeQueue *)hashtable_get(hashtable, key); //LockFreeQueue q; if (queue == NULL || (void *)queue == (void *)1) { queue = new LockFreeQueue(qsize); hashtable_put(hashtable, key, (void *)queue); } queue->reference++; LoggerFactory::getLogger().debug("SHMQueue constructor reference===%d", queue->reference.load()); } template < typename ELEM_T > SHMQueue::~SHMQueue() { SemUtil::dec( queue->mutex); queue->reference--; LoggerFactory::getLogger().debug("SHMQueue destructor reference===%d", queue->reference.load()); if(queue->reference.load() == 0) { delete queue; hashtable_t *hashtable = mm_get_hashtable(); hashtable_remove(hashtable, KEY); LoggerFactory::getLogger().debug("SHMQueue destructor delete queue"); } else { SemUtil::inc(queue->mutex); } } template < typename ELEM_T > inline uint32_t SHMQueue::size() { return queue->size(); } template < typename ELEM_T > inline bool SHMQueue::full() { return queue->full(); } template < typename ELEM_T > inline bool SHMQueue::empty() { return queue->empty(); } template < typename ELEM_T > inline bool SHMQueue::push(const ELEM_T &a_data) { return queue->push(a_data); } template < typename ELEM_T > inline bool SHMQueue::push_nowait(const ELEM_T &a_data) { return queue->push_nowait(a_data); } template < typename ELEM_T > inline bool SHMQueue::push_timeout(const ELEM_T &a_data, struct timespec * timeout) { return queue->push_timeout(a_data, timeout); } template < typename ELEM_T > inline bool SHMQueue::pop(ELEM_T &a_data) { return queue->pop(a_data); } template < typename ELEM_T > inline bool SHMQueue::pop_nowait(ELEM_T &a_data) { return queue->pop_nowait(a_data); } template < typename ELEM_T > inline bool SHMQueue::pop_timeout(ELEM_T &a_data, struct timespec * timeout) { return queue->pop_timeout(a_data, timeout); } template < typename ELEM_T > inline ELEM_T& SHMQueue::operator[](unsigned i) { return queue->operator[](i); } #endif