Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.95 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <tpcc/stdlike/condition_variable.hpp>
  4.  
  5. #include <cstddef>
  6. #include <deque>
  7. #include <mutex>
  8. #include <stdexcept>
  9.  
  10. namespace tpcc {
  11. namespace solutions {
  12.  
  13. class QueueClosed : public std::runtime_error {
  14. public:
  15. QueueClosed() : std::runtime_error("Queue closed for Puts") {
  16. }
  17. };
  18.  
  19. template <typename T, class Container = std::deque<T>>
  20. class BlockingQueue {
  21. public:
  22. // capacity == 0 means queue is unbounded
  23. explicit BlockingQueue(const size_t capacity = 0) : capacity_(capacity) {
  24. }
  25.  
  26. // throws QueueClosed exception after Close
  27. void Put(T item) {
  28. std::unique_lock<std::mutex> lock_(mutex_);
  29. while (IsFull() && !closed_) is_not_full_.wait(lock_);
  30. if (closed_)
  31. throw QueueClosed();
  32. items_.push_back(std::move(item));
  33. // items_.push_back(item);
  34. is_not_empty_.notify_one();
  35. // to be implemented
  36. }
  37.  
  38. bool Get(T& item) {
  39. std::unique_lock<std::mutex> lock_(mutex_);
  40. while (IsEmpty() && !closed_) is_not_empty_.wait(lock_);
  41. if (IsEmpty() && closed_)
  42. return false;
  43. item = std::move(items_.front());
  44. // item = items_.front();
  45. items_.pop_front();
  46. is_not_full_.notify_one();
  47. return true; // to be implemented
  48. }
  49.  
  50. // close queue for Puts
  51. void Close() {
  52. std::unique_lock<std::mutex> lock_(mutex_);
  53. if (closed_)
  54. return;
  55. closed_ = true;
  56. is_not_empty_.notify_all();
  57. is_not_full_.notify_all();
  58. return;
  59. }
  60.  
  61. // T(const T&) = delete; //some problems with items copy constructor
  62.  
  63. private:
  64. // internal predicates for condition variables
  65. tpcc::condition_variable is_not_empty_;
  66. tpcc::condition_variable is_not_full_;
  67.  
  68. bool IsFull() const {
  69. return (items_.size() == capacity_) && capacity_;
  70. // to be implemented
  71. }
  72.  
  73. bool IsEmpty() const {
  74. return items_.empty();
  75. // to be implemented
  76. }
  77.  
  78. private:
  79. size_t capacity_;
  80. Container items_;
  81. bool closed_{false};
  82. std::mutex mutex_;
  83. // use tpcc::condition_variable-s
  84. };
  85.  
  86. } // namespace solutions
  87. } // namespace tpcc
  88.  
  89. /*
  90. #pragma once
  91.  
  92. #include <tpcc/stdlike/condition_variable.hpp>
  93.  
  94. #include <cstddef>
  95. #include <deque>
  96. #include <mutex>
  97. #include <stdexcept>
  98.  
  99. namespace tpcc {
  100. namespace solutions {
  101.  
  102. class QueueClosed : public std::runtime_error {
  103. public:
  104. QueueClosed() : std::runtime_error("Queue closed for Puts") {
  105. }
  106. };
  107.  
  108. template <typename T, class Container = std::deque<T>>
  109. class BlockingQueue {
  110. public:
  111. // capacity == 0 means queue is unbounded
  112. explicit BlockingQueue(const size_t capacity = 0) : capacity_(capacity) {
  113. }
  114.  
  115. // throws QueueClosed exception after Close
  116. void Put(T item) {
  117. std::unique_lock<std::mutex> lock(mutex_);
  118.  
  119. // check whether the queue is full or closed
  120. not_full_.wait(lock, [this]() { return !IsFull() || closed_; });
  121.  
  122. if (closed_) {
  123. throw QueueClosed();
  124. }
  125.  
  126. queue_.push_back(std::move(item));
  127. lock.unlock();
  128. not_empty_.notify_one();
  129. }
  130.  
  131. bool Get(T& item) {
  132. std::unique_lock<std::mutex> lock(mutex_);
  133.  
  134. not_empty_.wait(lock, [this]() { return !IsEmpty() || closed_; });
  135.  
  136. if (closed_ && IsEmpty()) {
  137. return false;
  138. }
  139.  
  140. item = std::move(queue_.front());
  141. queue_.pop_front();
  142. lock.unlock();
  143. not_full_.notify_one();
  144. return true;
  145. }
  146.  
  147. // close queue for Puts
  148. void Close() {
  149. std::unique_lock<std::mutex> lock(mutex_);
  150. if (closed_) {
  151. return;
  152. }
  153. closed_ = true;
  154. lock.unlock();
  155. not_empty_.notify_all();
  156. not_full_.notify_all();
  157. }
  158.  
  159. private:
  160. tpcc::condition_variable not_empty_;
  161. tpcc::condition_variable not_full_;
  162.  
  163. bool IsFull() const {
  164. return capacity_ != 0 && queue_.size() == capacity_;
  165. }
  166.  
  167. bool IsEmpty() const {
  168. return queue_.empty();
  169. }
  170.  
  171. private:
  172. size_t capacity_;
  173. Container queue_;
  174. bool closed_{false};
  175. std::mutex mutex_;
  176. };
  177.  
  178. } // namespace solutions
  179. } // namespace tpcc*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement