| | |
| | | /** |
| | | * encapsulate lock_free_queue, populate in userspace |
| | | */ |
| | | |
| | | #ifndef __SHM_QUEUE_H__ |
| | | #define __SHM_QUEUE_H__ |
| | | |
| | |
| | | #include "sem_util.h" |
| | | #include "shm_allocator.h" |
| | | #include "usg_common.h" |
| | | // default Queue size |
| | | // #define LOCK_FREE_Q_DEFAULT_SIZE 16 |
| | | |
| | | |
| | | template <typename ELEM_T> class SHMQueue { |
| | | |
| | |
| | | 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, |
| | | const 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 int push(const ELEM_T &a_data); |
| | | inline int push_nowait(const ELEM_T &a_data); |
| | | inline int push_timeout(const ELEM_T &a_data, const struct timespec *timeout); |
| | | inline int pop(ELEM_T &a_data); |
| | | inline int pop_nowait(ELEM_T &a_data); |
| | | inline int pop_timeout(ELEM_T &a_data, struct timespec *timeout); |
| | | |
| | | inline ELEM_T &operator[](unsigned i); |
| | | |
| | |
| | | hashtable_put(hashtable, key, (void *)queue); |
| | | } |
| | | queue->reference++; |
| | | LoggerFactory::getLogger().debug("SHMQueue constructor reference===%d", queue->reference.load()); |
| | | // LoggerFactory::getLogger()->debug("SHMQueue constructor reference===%d", queue->reference.load()); |
| | | } |
| | | |
| | | template <typename ELEM_T> SHMQueue<ELEM_T>::~SHMQueue() { |
| | |
| | | return; |
| | | } |
| | | |
| | | SemUtil::dec(queue->mutex); |
| | | sem_wait(&(queue->mutex)); |
| | | queue->reference--; |
| | | // LoggerFactory::getLogger().debug("SHMQueue destructor reference===%d", |
| | | // LoggerFactory::getLogger()->debug("SHMQueue destructor reference===%d", |
| | | if (queue->reference.load() == 0) { |
| | | delete queue; |
| | | queue = NULL; |
| | | hashtable_t *hashtable = mm_get_hashtable(); |
| | | hashtable_remove(hashtable, KEY); |
| | | // 此时queue已经销毁,无需 SemUtil::inc(queue->mutex) |
| | | // 此时queue已经销毁,无需 sem_post(&(queue->mutex)) |
| | | // printf("SHMQueue destructor delete queue\n"); |
| | | } else { |
| | | SemUtil::inc(queue->mutex); |
| | | sem_post(&(queue->mutex)); |
| | | } |
| | | |
| | | } |
| | |
| | | } |
| | | |
| | | template <typename ELEM_T> |
| | | inline bool SHMQueue<ELEM_T>::push(const ELEM_T &a_data) { |
| | | inline int SHMQueue<ELEM_T>::push(const ELEM_T &a_data) { |
| | | return queue->push(a_data); |
| | | } |
| | | |
| | | template <typename ELEM_T> |
| | | inline bool SHMQueue<ELEM_T>::push_nowait(const ELEM_T &a_data) { |
| | | inline int SHMQueue<ELEM_T>::push_nowait(const ELEM_T &a_data) { |
| | | return queue->push_nowait(a_data); |
| | | } |
| | | |
| | | template <typename ELEM_T> |
| | | inline bool SHMQueue<ELEM_T>::push_timeout(const ELEM_T &a_data, |
| | | inline int SHMQueue<ELEM_T>::push_timeout(const ELEM_T &a_data, |
| | | const struct timespec *timeout) { |
| | | |
| | | return queue->push_timeout(a_data, timeout); |
| | | } |
| | | |
| | | template <typename ELEM_T> inline bool SHMQueue<ELEM_T>::pop(ELEM_T &a_data) { |
| | | template <typename ELEM_T> inline int SHMQueue<ELEM_T>::pop(ELEM_T &a_data) { |
| | | // printf("SHMQueue pop before\n"); |
| | | int rv = queue->pop(a_data); |
| | | // printf("SHMQueue after before\n"); |
| | |
| | | } |
| | | |
| | | template <typename ELEM_T> |
| | | inline bool SHMQueue<ELEM_T>::pop_nowait(ELEM_T &a_data) { |
| | | inline int SHMQueue<ELEM_T>::pop_nowait(ELEM_T &a_data) { |
| | | return queue->pop_nowait(a_data); |
| | | } |
| | | |
| | | template <typename ELEM_T> |
| | | inline bool SHMQueue<ELEM_T>::pop_timeout(ELEM_T &a_data, |
| | | struct timespec *timeout) { |
| | | inline int SHMQueue<ELEM_T>::pop_timeout(ELEM_T &a_data, struct timespec *timeout) { |
| | | return queue->pop_timeout(a_data, timeout); |
| | | } |
| | | |