#ifndef BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_QUEUE_BASE_HPP #define BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_QUEUE_BASE_HPP ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Vicente J. Botet Escriba 2013-2017. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/thread for documentation. // ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include namespace boost { namespace concurrent { namespace detail { template class sync_queue_base { public: typedef ValueType value_type; typedef Queue underlying_queue_type; typedef typename Queue::size_type size_type; typedef queue_op_status op_status; // Constructors/Assignment/Destructors BOOST_THREAD_NO_COPYABLE(sync_queue_base) inline sync_queue_base(); //template //inline explicit sync_queue(Range range); inline ~sync_queue_base(); // Observers inline bool empty() const; inline bool full() const; inline size_type size() const; inline bool closed() const; // Modifiers inline void close(); inline underlying_queue_type underlying_queue() { lock_guard lk(mtx_); return boost::move(data_); } protected: mutable mutex mtx_; condition_variable cond_; underlying_queue_type data_; bool closed_; inline bool empty(unique_lock& ) const BOOST_NOEXCEPT { return data_.empty(); } inline bool empty(lock_guard& ) const BOOST_NOEXCEPT { return data_.empty(); } inline size_type size(lock_guard& ) const BOOST_NOEXCEPT { return data_.size(); } inline bool closed(unique_lock& lk) const; inline bool closed(lock_guard& lk) const; inline void throw_if_closed(unique_lock&); inline void throw_if_closed(lock_guard&); inline bool not_empty_or_closed(unique_lock& ) const; inline bool wait_until_not_empty_or_closed(unique_lock& lk); template queue_op_status wait_until_not_empty_or_closed_until(unique_lock& lk, chrono::time_point const&tp); inline void notify_elem_added(unique_lock& ) { cond_.notify_all(); } inline void notify_elem_added(lock_guard& ) { cond_.notify_all(); } }; template sync_queue_base::sync_queue_base() : data_(), closed_(false) { BOOST_ASSERT(data_.empty()); } template sync_queue_base::~sync_queue_base() { } template void sync_queue_base::close() { { lock_guard lk(mtx_); closed_ = true; } cond_.notify_all(); } template bool sync_queue_base::closed() const { lock_guard lk(mtx_); return closed(lk); } template bool sync_queue_base::closed(unique_lock&) const { return closed_; } template bool sync_queue_base::closed(lock_guard&) const { return closed_; } template bool sync_queue_base::empty() const { lock_guard lk(mtx_); return empty(lk); } template bool sync_queue_base::full() const { return false; } template typename sync_queue_base::size_type sync_queue_base::size() const { lock_guard lk(mtx_); return size(lk); } template void sync_queue_base::throw_if_closed(unique_lock& lk) { if (closed(lk)) { BOOST_THROW_EXCEPTION( sync_queue_is_closed() ); } } template void sync_queue_base::throw_if_closed(lock_guard& lk) { if (closed(lk)) { BOOST_THROW_EXCEPTION( sync_queue_is_closed() ); } } template bool sync_queue_base::not_empty_or_closed(unique_lock& ) const { return ! data_.empty() || closed_; } template bool sync_queue_base::wait_until_not_empty_or_closed(unique_lock& lk) { cond_.wait(lk, boost::bind(&sync_queue_base::not_empty_or_closed, boost::ref(*this), boost::ref(lk))); if (! empty(lk)) return false; // success return true; // closed } template template queue_op_status sync_queue_base::wait_until_not_empty_or_closed_until(unique_lock& lk, chrono::time_point const&tp) { if (! cond_.wait_until(lk, tp, boost::bind(&sync_queue_base::not_empty_or_closed, boost::ref(*this), boost::ref(lk)))) return queue_op_status::timeout; if (! empty(lk)) return queue_op_status::success; return queue_op_status::closed; } } // detail } // concurrent } // boost #include #endif