#ifndef BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP #define BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Vicente J. Botet Escriba 2013-2014. 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 #include namespace boost { namespace concurrent { namespace detail { template class sync_deque_base { public: typedef ValueType value_type; typedef Queue underlying_queue_type; typedef typename Queue::size_type size_type; typedef queue_op_status op_status; typedef typename chrono::steady_clock clock; typedef typename clock::duration duration; typedef typename clock::time_point time_point; // Constructors/Assignment/Destructors BOOST_THREAD_NO_COPYABLE(sync_deque_base) inline sync_deque_base(); //template //inline explicit sync_deque(Range range); inline ~sync_deque_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 not_empty_; 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 void wait_until_not_empty(unique_lock& lk); inline bool wait_until_not_empty_or_closed(unique_lock& lk); inline queue_op_status wait_until_not_empty_until(unique_lock& lk, time_point const&); inline void notify_not_empty_if_needed(unique_lock& ) { not_empty_.notify_one(); } inline void notify_not_empty_if_needed(lock_guard& ) { not_empty_.notify_one(); } }; template sync_deque_base::sync_deque_base() : data_(), closed_(false) { BOOST_ASSERT(data_.empty()); } template sync_deque_base::~sync_deque_base() { } template void sync_deque_base::close() { { lock_guard lk(mtx_); closed_ = true; } not_empty_.notify_all(); } template bool sync_deque_base::closed() const { lock_guard lk(mtx_); return closed(lk); } template bool sync_deque_base::closed(unique_lock&) const { return closed_; } template bool sync_deque_base::closed(lock_guard&) const { return closed_; } template bool sync_deque_base::empty() const { lock_guard lk(mtx_); return empty(lk); } template bool sync_deque_base::full() const { return false; } template typename sync_deque_base::size_type sync_deque_base::size() const { lock_guard lk(mtx_); return size(lk); } template void sync_deque_base::throw_if_closed(unique_lock& lk) { if (closed(lk)) { BOOST_THROW_EXCEPTION( sync_deque_is_closed() ); } } template void sync_deque_base::throw_if_closed(lock_guard& lk) { if (closed(lk)) { BOOST_THROW_EXCEPTION( sync_deque_is_closed() ); } } template void sync_deque_base::wait_until_not_empty(unique_lock& lk) { for (;;) { if (! empty(lk)) break; throw_if_closed(lk); not_empty_.wait(lk); } } template bool sync_deque_base::wait_until_not_empty_or_closed(unique_lock& lk) { for (;;) { if (! empty(lk)) break; if (closed(lk)) return true; not_empty_.wait(lk); } return false; } template queue_op_status sync_deque_base::wait_until_not_empty_until(unique_lock& lk, time_point const&tp) { for (;;) { if (! empty(lk)) return queue_op_status::success; throw_if_closed(lk); if (not_empty_.wait_until(lk, tp) == cv_status::timeout ) return queue_op_status::timeout; } } } // detail } // concurrent } // boost #include #endif