/** * encapsulate lock_free_queue, populate in userspace */ #ifndef __SHM_QUEUE_H__ #define __SHM_QUEUE_H__ #include "hashtable.h" #include "logger_factory.h" #include "sem_util.h" #include "shm_allocator.h" #include "usg_common.h" #include "array_lock_free_sem_queue.h" #include "lock_free_queue.h" #include "bus_error.h" template class SHMQueue { private: const int mkey; hashtable_t * hashtable; // 是否是key对应的共享队列的真正拥有者,也就是说是bind到key上的,不是attach到key上的对象 bool owner; size_t mqsize; public: /// @brief constructor of the class SHMQueue(size_t qsize = 16); ~SHMQueue(); bool bind(int key, bool force) ; bool attach(int key); int get_key(); uint32_t size(); bool full(); bool empty(); int push(const ELEM_T &a_data, const struct timespec *timeout=NULL, int flag=0); int pop(ELEM_T &a_data, const struct timespec *timeout=NULL, int flag=0); ELEM_T &operator[](unsigned i); 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 SHMQueue::SHMQueue(size_t qsize): mqsize(qsize) { hashtable = mm_get_hashtable(); owner = false; mkey = 0; // queue = (LockFreeQueue *)hashtable_get(hashtable, key); // 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 SHMQueue::~SHMQueue() { LoggerFactory::getLogger()->debug("SHMQueue destroy"); } template bool SHMQueue::bind(int key, bool force) { void *tmp_ptr = hashtable_get(hashtable, key); if (tmp_ptr == NULL || tmp_ptr == (void *)1 || force) { queue = new LockFreeQueue(mqsize); hashtable_put(hashtable, key, (void *)queue); mkey = key; owner = true; return true; } return false; } template bool SHMQueue::attach(int key) { void *tmp_ptr = hashtable_get(hashtable, key); if (tmp_ptr == NULL || tmp_ptr == (void *)1) { return false; } mkey = key; queue = (LockFreeQueue *)tmp_ptr; return true; } template int SHMQueue::get_key() { return mkey; } template uint32_t SHMQueue::size() { return queue->size(); } template bool SHMQueue::full() { return queue->full(); } template bool SHMQueue::empty() { return queue->empty(); } template int SHMQueue::push(const ELEM_T &a_data, const struct timespec *timeout, int flag) { int rv = queue->push(a_data, timeout, flag); if(rv == 0) { return 0; } if(rv == ETIMEDOUT) return EBUS_TIMEOUT; else { LoggerFactory::getLogger()->error("LockFreeQueue push_timeout: %s", bus_strerror(rv)); return rv; } } template int SHMQueue::pop(ELEM_T &a_data, const struct timespec *timeout, int flag) { int rv = queue->pop(a_data, timeout, flag); if(rv == 0) { return 0; } if(rv == ETIMEDOUT) return EBUS_TIMEOUT; else { LoggerFactory::getLogger()->error("LockFreeQueue pop_timeout: %s", bus_strerror(rv)); return rv; } return rv; } template ELEM_T &SHMQueue::operator[](unsigned i) { return queue->operator[](i); } #endif