Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-26 09:57:45

0001 #ifndef BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP
0002 #define BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP
0003 
0004 //////////////////////////////////////////////////////////////////////////////
0005 //
0006 // (C) Copyright Vicente J. Botet Escriba 2013-2017. Distributed under the Boost
0007 // Software License, Version 1.0. (See accompanying file
0008 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 // See http://www.boost.org/libs/thread for documentation.
0011 //
0012 //////////////////////////////////////////////////////////////////////////////
0013 
0014 #include <boost/bind/bind.hpp>
0015 
0016 #include <boost/thread/detail/config.hpp>
0017 #include <boost/thread/condition_variable.hpp>
0018 #include <boost/thread/detail/move.hpp>
0019 #include <boost/thread/mutex.hpp>
0020 #include <boost/thread/concurrent_queues/queue_op_status.hpp>
0021 
0022 #include <boost/chrono/time_point.hpp>
0023 #include <boost/throw_exception.hpp>
0024 
0025 #include <boost/config/abi_prefix.hpp>
0026 
0027 namespace boost
0028 {
0029 namespace concurrent
0030 {
0031 namespace detail
0032 {
0033 
0034   template <class ValueType, class Queue>
0035   class sync_deque_base
0036   {
0037   public:
0038     typedef ValueType value_type;
0039     typedef Queue underlying_queue_type;
0040     typedef typename Queue::size_type size_type;
0041     typedef queue_op_status op_status;
0042 
0043     // Constructors/Assignment/Destructors
0044     BOOST_THREAD_NO_COPYABLE(sync_deque_base)
0045     inline sync_deque_base();
0046     //template <typename Range>
0047     //inline explicit sync_deque(Range range);
0048     inline ~sync_deque_base();
0049 
0050     // Observers
0051     inline bool empty() const;
0052     inline bool full() const;
0053     inline size_type size() const;
0054     inline bool closed() const;
0055 
0056     // Modifiers
0057     inline void close();
0058 
0059     inline underlying_queue_type underlying_queue() {
0060       lock_guard<mutex> lk(mtx_);
0061       return boost::move(data_);
0062     }
0063 
0064   protected:
0065     mutable mutex mtx_;
0066     condition_variable cond_;
0067     underlying_queue_type data_;
0068     bool closed_;
0069 
0070     inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
0071     {
0072       return data_.empty();
0073     }
0074     inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
0075     {
0076       return data_.empty();
0077     }
0078 
0079     inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
0080     {
0081       return data_.size();
0082     }
0083     inline bool closed(unique_lock<mutex>& lk) const;
0084     inline bool closed(lock_guard<mutex>& lk) const;
0085 
0086     inline void throw_if_closed(unique_lock<mutex>&);
0087     inline void throw_if_closed(lock_guard<mutex>&);
0088 
0089     inline bool not_empty_or_closed(unique_lock<mutex>& ) const;
0090 
0091     inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
0092     template <class WClock, class Duration>
0093     queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
0094 
0095     inline void notify_elem_added(unique_lock<mutex>& )
0096     {
0097       cond_.notify_all();
0098     }
0099     inline void notify_elem_added(lock_guard<mutex>& )
0100     {
0101       cond_.notify_all();
0102     }
0103 
0104   };
0105 
0106   template <class ValueType, class Queue>
0107   sync_deque_base<ValueType, Queue>::sync_deque_base() :
0108     data_(), closed_(false)
0109   {
0110     BOOST_ASSERT(data_.empty());
0111   }
0112 
0113   template <class ValueType, class Queue>
0114   sync_deque_base<ValueType, Queue>::~sync_deque_base()
0115   {
0116   }
0117 
0118   template <class ValueType, class Queue>
0119   void sync_deque_base<ValueType, Queue>::close()
0120   {
0121     {
0122       lock_guard<mutex> lk(mtx_);
0123       closed_ = true;
0124     }
0125     cond_.notify_all();
0126   }
0127 
0128   template <class ValueType, class Queue>
0129   bool sync_deque_base<ValueType, Queue>::closed() const
0130   {
0131     lock_guard<mutex> lk(mtx_);
0132     return closed(lk);
0133   }
0134   template <class ValueType, class Queue>
0135   bool sync_deque_base<ValueType, Queue>::closed(unique_lock<mutex>&) const
0136   {
0137     return closed_;
0138   }
0139   template <class ValueType, class Queue>
0140   bool sync_deque_base<ValueType, Queue>::closed(lock_guard<mutex>&) const
0141   {
0142     return closed_;
0143   }
0144 
0145   template <class ValueType, class Queue>
0146   bool sync_deque_base<ValueType, Queue>::empty() const
0147   {
0148     lock_guard<mutex> lk(mtx_);
0149     return empty(lk);
0150   }
0151   template <class ValueType, class Queue>
0152   bool sync_deque_base<ValueType, Queue>::full() const
0153   {
0154     return false;
0155   }
0156 
0157   template <class ValueType, class Queue>
0158   typename sync_deque_base<ValueType, Queue>::size_type sync_deque_base<ValueType, Queue>::size() const
0159   {
0160     lock_guard<mutex> lk(mtx_);
0161     return size(lk);
0162   }
0163 
0164   template <class ValueType, class Queue>
0165   void sync_deque_base<ValueType, Queue>::throw_if_closed(unique_lock<mutex>& lk)
0166   {
0167     if (closed(lk))
0168     {
0169       BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
0170     }
0171   }
0172   template <class ValueType, class Queue>
0173   void sync_deque_base<ValueType, Queue>::throw_if_closed(lock_guard<mutex>& lk)
0174   {
0175     if (closed(lk))
0176     {
0177       BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
0178     }
0179   }
0180 
0181   template <class ValueType, class Queue>
0182   bool sync_deque_base<ValueType, Queue>::not_empty_or_closed(unique_lock<mutex>& ) const
0183   {
0184     return ! data_.empty() || closed_;
0185   }
0186 
0187   template <class ValueType, class Queue>
0188   bool sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
0189   {
0190     cond_.wait(lk, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)));
0191     if (! empty(lk)) return false; // success
0192     return true; // closed
0193   }
0194 
0195   template <class ValueType, class Queue>
0196   template <class WClock, class Duration>
0197   queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
0198   {
0199     if (! cond_.wait_until(lk, tp, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))))
0200       return queue_op_status::timeout;
0201     if (! empty(lk)) return queue_op_status::success;
0202     return queue_op_status::closed;
0203   }
0204 
0205 } // detail
0206 } // concurrent
0207 } // boost
0208 
0209 #include <boost/config/abi_suffix.hpp>
0210 
0211 #endif