diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-03-21 15:45:20 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-03-21 15:46:37 +0900 |
commit | 733b5d5ae2c5d625211e2985ac25728ac3f54883 (patch) | |
tree | a5b214744b256f07e1dc2bd7273035a7808c659f /boost/thread/concurrent_queues/sync_queue.hpp | |
parent | 08c1e93fa36a49f49325a07fe91ff92c964c2b6c (diff) | |
download | boost-733b5d5ae2c5d625211e2985ac25728ac3f54883.tar.gz boost-733b5d5ae2c5d625211e2985ac25728ac3f54883.tar.bz2 boost-733b5d5ae2c5d625211e2985ac25728ac3f54883.zip |
Imported Upstream version 1.58.0upstream/1.58.0
Change-Id: If0072143aa26874812e0db6872e1efb10a3e5e94
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/thread/concurrent_queues/sync_queue.hpp')
-rw-r--r-- | boost/thread/concurrent_queues/sync_queue.hpp | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/boost/thread/concurrent_queues/sync_queue.hpp b/boost/thread/concurrent_queues/sync_queue.hpp new file mode 100644 index 0000000000..7183c9cad8 --- /dev/null +++ b/boost/thread/concurrent_queues/sync_queue.hpp @@ -0,0 +1,328 @@ +#ifndef BOOST_THREAD_CONCURRENT_QUEUES_SYNC_QUEUE_HPP +#define BOOST_THREAD_CONCURRENT_QUEUES_SYNC_QUEUE_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 <boost/thread/detail/config.hpp> +#include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp> +#include <boost/thread/concurrent_queues/queue_op_status.hpp> +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/csbl/devector.hpp> +#include <boost/thread/detail/move.hpp> +#include <boost/thread/mutex.hpp> + +#include <boost/throw_exception.hpp> +#include <boost/smart_ptr/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ +namespace concurrent +{ + template <class ValueType, class Container = csbl::devector<ValueType> > + class sync_queue + : public detail::sync_queue_base<ValueType, Container > + { + typedef detail::sync_queue_base<ValueType, Container > super; + + public: + typedef ValueType value_type; + //typedef typename super::value_type value_type; // fixme + typedef typename super::underlying_queue_type underlying_queue_type; + typedef typename super::size_type size_type; + typedef typename super::op_status op_status; + + // Constructors/Assignment/Destructors + BOOST_THREAD_NO_COPYABLE(sync_queue) + inline sync_queue(); + //template <class Range> + //inline explicit sync_queue(Range range); + inline ~sync_queue(); + + // Modifiers + + inline void push(const value_type& x); + inline queue_op_status try_push(const value_type& x); + inline queue_op_status nonblocking_push(const value_type& x); + inline queue_op_status wait_push(const value_type& x); + inline void push(BOOST_THREAD_RV_REF(value_type) x); + inline queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x); + inline queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x); + inline queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x); + + // Observers/Modifiers + inline void pull(value_type&); + // enable_if is_nothrow_copy_movable<value_type> + inline value_type pull(); + + inline queue_op_status try_pull(value_type&); + inline queue_op_status nonblocking_pull(value_type&); + inline queue_op_status wait_pull(ValueType& elem); + + private: + + inline queue_op_status try_pull(value_type& x, unique_lock<mutex>& lk); + inline queue_op_status wait_pull(value_type& x, unique_lock<mutex>& lk); + inline queue_op_status try_push(const value_type& x, unique_lock<mutex>& lk); + inline queue_op_status wait_push(const value_type& x, unique_lock<mutex>& lk); + inline queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk); + inline queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk); + + inline void pull(value_type& elem, unique_lock<mutex>& ) + { + elem = boost::move(super::data_.front()); + super::data_.pop_front(); + } + inline value_type pull(unique_lock<mutex>& ) + { + value_type e = boost::move(super::data_.front()); + super::data_.pop_front(); + return boost::move(e); + } + + inline void push(const value_type& elem, unique_lock<mutex>& lk) + { + super::data_.push_back(elem); + super::notify_not_empty_if_needed(lk); + } + + inline void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk) + { + super::data_.push_back(boost::move(elem)); + super::notify_not_empty_if_needed(lk); + } + }; + + template <class ValueType, class Container> + sync_queue<ValueType, Container>::sync_queue() : + super() + { + } + +// template <class ValueType, class Container> +// template <class Range> +// explicit sync_queue<ValueType, Container>::sync_queue(Range range) : +// data_(), closed_(false) +// { +// try +// { +// typedef typename Range::iterator iterator_t; +// iterator_t first = boost::begin(range); +// iterator_t end = boost::end(range); +// for (iterator_t cur = first; cur != end; ++cur) +// { +// data_.push(boost::move(*cur));; +// } +// notify_not_empty_if_needed(lk); +// } +// catch (...) +// { +// delete[] data_; +// } +// } + + template <class ValueType, class Container> + sync_queue<ValueType, Container>::~sync_queue() + { + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::try_pull(ValueType& elem, unique_lock<mutex>& lk) + { + if (super::empty(lk)) + { + if (super::closed(lk)) return queue_op_status::closed; + return queue_op_status::empty; + } + pull(elem, lk); + return queue_op_status::success; + } + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::wait_pull(ValueType& elem, unique_lock<mutex>& lk) + { + if (super::empty(lk)) + { + if (super::closed(lk)) return queue_op_status::closed; + } + bool has_been_closed = super::wait_until_not_empty_or_closed(lk); + if (has_been_closed) return queue_op_status::closed; + pull(elem, lk); + return queue_op_status::success; + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::try_pull(ValueType& elem) + { + unique_lock<mutex> lk(super::mtx_); + return try_pull(elem, lk); + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::wait_pull(ValueType& elem) + { + unique_lock<mutex> lk(super::mtx_); + return wait_pull(elem, lk); + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::nonblocking_pull(ValueType& elem) + { + unique_lock<mutex> lk(super::mtx_, try_to_lock); + if (!lk.owns_lock()) + { + return queue_op_status::busy; + } + return try_pull(elem, lk); + } + + template <class ValueType, class Container> + void sync_queue<ValueType, Container>::pull(ValueType& elem) + { + unique_lock<mutex> lk(super::mtx_); + super::wait_until_not_empty(lk); + pull(elem, lk); + } + + // enable if ValueType is nothrow movable + template <class ValueType, class Container> + ValueType sync_queue<ValueType, Container>::pull() + { + unique_lock<mutex> lk(super::mtx_); + super::wait_until_not_empty(lk); + return pull(lk); + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::try_push(const ValueType& elem, unique_lock<mutex>& lk) + { + if (super::closed(lk)) return queue_op_status::closed; + push(elem, lk); + return queue_op_status::success; + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::try_push(const ValueType& elem) + { + unique_lock<mutex> lk(super::mtx_); + return try_push(elem, lk); + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::wait_push(const ValueType& elem, unique_lock<mutex>& lk) + { + if (super::closed(lk)) return queue_op_status::closed; + push(elem, lk); + return queue_op_status::success; + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::wait_push(const ValueType& elem) + { + unique_lock<mutex> lk(super::mtx_); + return wait_push(elem, lk); + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::nonblocking_push(const ValueType& elem) + { + unique_lock<mutex> lk(super::mtx_, try_to_lock); + if (!lk.owns_lock()) return queue_op_status::busy; + return try_push(elem, lk); + } + + template <class ValueType, class Container> + void sync_queue<ValueType, Container>::push(const ValueType& elem) + { + unique_lock<mutex> lk(super::mtx_); + super::throw_if_closed(lk); + push(elem, lk); + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::try_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk) + { + if (super::closed(lk)) return queue_op_status::closed; + push(boost::move(elem), lk); + return queue_op_status::success; + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::try_push(BOOST_THREAD_RV_REF(ValueType) elem) + { + unique_lock<mutex> lk(super::mtx_); + return try_push(boost::move(elem), lk); + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::wait_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk) + { + if (super::closed(lk)) return queue_op_status::closed; + push(boost::move(elem), lk); + return queue_op_status::success; + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::wait_push(BOOST_THREAD_RV_REF(ValueType) elem) + { + unique_lock<mutex> lk(super::mtx_); + return wait_push(boost::move(elem), lk); + } + + template <class ValueType, class Container> + queue_op_status sync_queue<ValueType, Container>::nonblocking_push(BOOST_THREAD_RV_REF(ValueType) elem) + { + unique_lock<mutex> lk(super::mtx_, try_to_lock); + if (!lk.owns_lock()) + { + return queue_op_status::busy; + } + return try_push(boost::move(elem), lk); + } + + template <class ValueType, class Container> + void sync_queue<ValueType, Container>::push(BOOST_THREAD_RV_REF(ValueType) elem) + { + unique_lock<mutex> lk(super::mtx_); + super::throw_if_closed(lk); + push(boost::move(elem), lk); + } + + template <class ValueType, class Container> + sync_queue<ValueType, Container>& operator<<(sync_queue<ValueType, Container>& sbq, BOOST_THREAD_RV_REF(ValueType) elem) + { + sbq.push(boost::move(elem)); + return sbq; + } + + template <class ValueType, class Container> + sync_queue<ValueType, Container>& operator<<(sync_queue<ValueType, Container>& sbq, ValueType const&elem) + { + sbq.push(elem); + return sbq; + } + + template <class ValueType, class Container> + sync_queue<ValueType, Container>& operator>>(sync_queue<ValueType, Container>& sbq, ValueType &elem) + { + sbq.pull(elem); + return sbq; + } + +} +using concurrent::sync_queue; + +} + +#include <boost/config/abi_suffix.hpp> + +#endif |