Queue.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #ifndef BELL_QUEUE_H
  2. #define BELL_QUEUE_H
  3. #include <queue>
  4. #include <atomic>
  5. #include <condition_variable>
  6. #include <atomic>
  7. namespace bell
  8. {
  9. template <typename dataType>
  10. class Queue
  11. {
  12. private:
  13. /// Queue
  14. std::queue<dataType> m_queue;
  15. /// Mutex to controll multiple access
  16. mutable std::mutex m_mutex;
  17. /// Conditional variable used to fire event
  18. std::condition_variable m_cv;
  19. /// Atomic variable used to terminate immediately wpop and wtpop functions
  20. std::atomic<bool> m_forceExit = false;
  21. public:
  22. /// <summary> Add a new element in the queue. </summary>
  23. /// <param name="data"> New element. </param>
  24. void push(dataType const &data)
  25. {
  26. m_forceExit.store(false);
  27. std::unique_lock<std::mutex> lk(m_mutex);
  28. m_queue.push(data);
  29. lk.unlock();
  30. m_cv.notify_one();
  31. }
  32. /// <summary> Check queue empty. </summary>
  33. /// <returns> True if the queue is empty. </returns>
  34. bool isEmpty() const
  35. {
  36. std::unique_lock<std::mutex> lk(m_mutex);
  37. return m_queue.empty();
  38. }
  39. /// <summary> Pop element from queue. </summary>
  40. /// <param name="popped_value"> [in,out] Element. </param>
  41. /// <returns> false if the queue is empty. </returns>
  42. bool pop(dataType &popped_value)
  43. {
  44. std::unique_lock<std::mutex> lk(m_mutex);
  45. if (m_queue.empty())
  46. {
  47. return false;
  48. }
  49. else
  50. {
  51. popped_value = m_queue.front();
  52. m_queue.pop();
  53. return true;
  54. }
  55. }
  56. /// <summary> Wait and pop an element in the queue. </summary>
  57. /// <param name="popped_value"> [in,out] Element. </param>
  58. /// <returns> False for forced exit. </returns>
  59. bool wpop(dataType &popped_value)
  60. {
  61. std::unique_lock<std::mutex> lk(m_mutex);
  62. m_cv.wait(lk, [&]() -> bool
  63. { return !m_queue.empty() || m_forceExit.load(); });
  64. if (m_forceExit.load())
  65. return false;
  66. popped_value = m_queue.front();
  67. m_queue.pop();
  68. return true;
  69. }
  70. /// <summary> Timed wait and pop an element in the queue. </summary>
  71. /// <param name="popped_value"> [in,out] Element. </param>
  72. /// <param name="milliseconds"> [in] Wait time. </param>
  73. /// <returns> False for timeout or forced exit. </returns>
  74. bool wtpop(dataType &popped_value, long milliseconds = 1000)
  75. {
  76. std::unique_lock<std::mutex> lk(m_mutex);
  77. m_cv.wait_for(lk, std::chrono::milliseconds(milliseconds), [&]() -> bool
  78. { return !m_queue.empty() || m_forceExit.load(); });
  79. if (m_forceExit.load())
  80. return false;
  81. if (m_queue.empty())
  82. return false;
  83. popped_value = m_queue.front();
  84. m_queue.pop();
  85. return true;
  86. }
  87. /// <summary> Queue size. </summary>
  88. int size()
  89. {
  90. std::unique_lock<std::mutex> lk(m_mutex);
  91. return static_cast<int>(m_queue.size());
  92. }
  93. /// <summary> Free the queue and force stop. </summary>
  94. void clear()
  95. {
  96. m_forceExit.store(true);
  97. std::unique_lock<std::mutex> lk(m_mutex);
  98. while (!m_queue.empty())
  99. {
  100. //delete m_queue.front();
  101. m_queue.pop();
  102. }
  103. lk.unlock();
  104. m_cv.notify_one();
  105. }
  106. /// <summary> Check queue in forced exit state. </summary>
  107. bool isExit() const
  108. {
  109. return m_forceExit.load();
  110. }
  111. };
  112. }
  113. #endif