Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <tpcc/stdlike/condition_variable.hpp>
- #include <cstddef>
- #include <deque>
- #include <mutex>
- #include <stdexcept>
- namespace tpcc {
- namespace solutions {
- class QueueClosed : public std::runtime_error {
- public:
- QueueClosed() : std::runtime_error("Queue closed for Puts") {
- }
- };
- template <typename T, class Container = std::deque<T>>
- class BlockingQueue {
- public:
- // capacity == 0 means queue is unbounded
- explicit BlockingQueue(const size_t capacity = 0) : capacity_(capacity) {
- }
- // throws QueueClosed exception after Close
- void Put(T item) {
- std::unique_lock<std::mutex> lock_(mutex_);
- while (IsFull() && !closed_) is_not_full_.wait(lock_);
- if (closed_)
- throw QueueClosed();
- items_.push_back(std::move(item));
- // items_.push_back(item);
- is_not_empty_.notify_one();
- // to be implemented
- }
- bool Get(T& item) {
- std::unique_lock<std::mutex> lock_(mutex_);
- while (IsEmpty() && !closed_) is_not_empty_.wait(lock_);
- if (IsEmpty() && closed_)
- return false;
- item = std::move(items_.front());
- // item = items_.front();
- items_.pop_front();
- is_not_full_.notify_one();
- return true; // to be implemented
- }
- // close queue for Puts
- void Close() {
- std::unique_lock<std::mutex> lock_(mutex_);
- if (closed_)
- return;
- closed_ = true;
- is_not_empty_.notify_all();
- is_not_full_.notify_all();
- return;
- }
- // T(const T&) = delete; //some problems with items copy constructor
- private:
- // internal predicates for condition variables
- tpcc::condition_variable is_not_empty_;
- tpcc::condition_variable is_not_full_;
- bool IsFull() const {
- return (items_.size() == capacity_) && capacity_;
- // to be implemented
- }
- bool IsEmpty() const {
- return items_.empty();
- // to be implemented
- }
- private:
- size_t capacity_;
- Container items_;
- bool closed_{false};
- std::mutex mutex_;
- // use tpcc::condition_variable-s
- };
- } // namespace solutions
- } // namespace tpcc
- /*
- #pragma once
- #include <tpcc/stdlike/condition_variable.hpp>
- #include <cstddef>
- #include <deque>
- #include <mutex>
- #include <stdexcept>
- namespace tpcc {
- namespace solutions {
- class QueueClosed : public std::runtime_error {
- public:
- QueueClosed() : std::runtime_error("Queue closed for Puts") {
- }
- };
- template <typename T, class Container = std::deque<T>>
- class BlockingQueue {
- public:
- // capacity == 0 means queue is unbounded
- explicit BlockingQueue(const size_t capacity = 0) : capacity_(capacity) {
- }
- // throws QueueClosed exception after Close
- void Put(T item) {
- std::unique_lock<std::mutex> lock(mutex_);
- // check whether the queue is full or closed
- not_full_.wait(lock, [this]() { return !IsFull() || closed_; });
- if (closed_) {
- throw QueueClosed();
- }
- queue_.push_back(std::move(item));
- lock.unlock();
- not_empty_.notify_one();
- }
- bool Get(T& item) {
- std::unique_lock<std::mutex> lock(mutex_);
- not_empty_.wait(lock, [this]() { return !IsEmpty() || closed_; });
- if (closed_ && IsEmpty()) {
- return false;
- }
- item = std::move(queue_.front());
- queue_.pop_front();
- lock.unlock();
- not_full_.notify_one();
- return true;
- }
- // close queue for Puts
- void Close() {
- std::unique_lock<std::mutex> lock(mutex_);
- if (closed_) {
- return;
- }
- closed_ = true;
- lock.unlock();
- not_empty_.notify_all();
- not_full_.notify_all();
- }
- private:
- tpcc::condition_variable not_empty_;
- tpcc::condition_variable not_full_;
- bool IsFull() const {
- return capacity_ != 0 && queue_.size() == capacity_;
- }
- bool IsEmpty() const {
- return queue_.empty();
- }
- private:
- size_t capacity_;
- Container queue_;
- bool closed_{false};
- std::mutex mutex_;
- };
- } // namespace solutions
- } // namespace tpcc*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement