stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,209 @@
#ifndef BOOST_THREAD_CONCURRENT_DEQUE_ADAPTOR_HPP
#define BOOST_THREAD_CONCURRENT_DEQUE_ADAPTOR_HPP
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 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/detail/move.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/thread/concurrent_queues/deque_base.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
namespace detail
{
template <typename Queue>
class deque_adaptor_copyable_only :
public boost::deque_base<typename Queue::value_type, typename Queue::size_type>
{
Queue queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
deque_adaptor_copyable_only() {}
// Observers
bool empty() const { return queue.empty(); }
bool full() const { return queue.full(); }
size_type size() const { return queue.size(); }
bool closed() const { return queue.closed(); }
// Modifiers
void close() { queue.close(); }
void push_back(const value_type& x) { queue.push_back(x); }
void pull_front(value_type& x) { queue.pull_front(x); };
value_type pull_front() { return queue.pull_front(); }
queue_op_status try_push_back(const value_type& x) { return queue.try_push_back(x); }
queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
queue_op_status nonblocking_push_back(const value_type& x) { return queue.nonblocking_push_back(x); }
queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
queue_op_status wait_push_back(const value_type& x) { return queue.wait_push_back(x); }
queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
};
template <typename Queue>
class deque_adaptor_movable_only :
public boost::deque_base<typename Queue::value_type, typename Queue::size_type>
{
Queue queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
deque_adaptor_movable_only() {}
// Observers
bool empty() const { return queue.empty(); }
bool full() const { return queue.full(); }
size_type size() const { return queue.size(); }
bool closed() const { return queue.closed(); }
// Modifiers
void close() { queue.close(); }
void pull_front(value_type& x) { queue.pull_front(x); };
// enable_if is_nothrow_copy_movable<value_type>
value_type pull_front() { return queue.pull_front(); }
queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
void push_back(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(boost::move(x)); }
queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(boost::move(x)); }
queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(boost::move(x)); }
queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(boost::move(x)); }
};
template <typename Queue>
class deque_adaptor_copyable_and_movable :
public boost::deque_base<typename Queue::value_type, typename Queue::size_type>
{
Queue queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
deque_adaptor_copyable_and_movable() {}
// Observers
bool empty() const { return queue.empty(); }
bool full() const { return queue.full(); }
size_type size() const { return queue.size(); }
bool closed() const { return queue.closed(); }
// Modifiers
void close() { queue.close(); }
void push_back(const value_type& x) { queue.push_back(x); }
void pull_front(value_type& x) { queue.pull_front(x); };
// enable_if is_nothrow_copy_movable<value_type>
value_type pull_front() { return queue.pull_front(); }
queue_op_status try_push_back(const value_type& x) { return queue.try_push_back(x); }
queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
queue_op_status nonblocking_push_back(const value_type& x) { return queue.nonblocking_push_back(x); }
queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
queue_op_status wait_push_back(const value_type& x) { return queue.wait_push_back(x); }
queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
void push_back(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(boost::move(x)); }
queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(boost::move(x)); }
queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(boost::move(x)); }
queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(boost::move(x)); }
};
template <class Q, class T,
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined __GNUC__ && ! defined __clang__
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif // __GNUC__
#elif defined _MSC_VER
#if _MSC_VER < 1700
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif // _MSC_VER
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif
#else
bool Copyable = is_copy_constructible<T>::value,
bool Movable = has_move_emulation_enabled<T>::value
#endif
>
struct deque_adaptor;
template <class Q, class T>
struct deque_adaptor<Q, T, true, true> {
typedef deque_adaptor_copyable_and_movable<Q> type;
};
template <class Q, class T>
struct deque_adaptor<Q, T, true, false> {
typedef deque_adaptor_copyable_only<Q> type;
};
template <class Q, class T>
struct deque_adaptor<Q, T, false, true> {
typedef deque_adaptor_movable_only<Q> type;
};
}
template <typename Queue>
class deque_adaptor :
public detail::deque_adaptor<Queue, typename Queue::value_type>::type
{
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
virtual ~deque_adaptor() {};
};
}
using concurrent::deque_adaptor;
}
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,202 @@
#ifndef BOOST_THREAD_CONCURRENT_DEQUE_BASE_HPP
#define BOOST_THREAD_CONCURRENT_DEQUE_BASE_HPP
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 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/detail/move.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
namespace detail
{
template <typename ValueType, class SizeType>
class deque_base_copyable_only
{
public:
typedef ValueType value_type;
typedef SizeType size_type;
// Constructors/Assignment/Destructors
virtual ~deque_base_copyable_only() {};
// Observers
virtual bool empty() const = 0;
virtual bool full() const = 0;
virtual size_type size() const = 0;
virtual bool closed() const = 0;
// Modifiers
virtual void close() = 0;
virtual void push_back(const value_type& x) = 0;
virtual void pull_front(value_type&) = 0;
virtual value_type pull_front() = 0;
virtual queue_op_status try_push_back(const value_type& x) = 0;
virtual queue_op_status try_pull_front(value_type&) = 0;
virtual queue_op_status nonblocking_push_back(const value_type& x) = 0;
virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
virtual queue_op_status wait_push_back(const value_type& x) = 0;
virtual queue_op_status wait_pull_front(value_type& elem) = 0;
};
template <typename ValueType, class SizeType>
class deque_base_movable_only
{
public:
typedef ValueType value_type;
typedef SizeType size_type;
// Constructors/Assignment/Destructors
virtual ~deque_base_movable_only() {};
// Observers
virtual bool empty() const = 0;
virtual bool full() const = 0;
virtual size_type size() const = 0;
virtual bool closed() const = 0;
// Modifiers
virtual void close() = 0;
virtual void pull_front(value_type&) = 0;
// enable_if is_nothrow_movable<value_type>
virtual value_type pull_front() = 0;
virtual queue_op_status try_pull_front(value_type&) = 0;
virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
virtual queue_op_status wait_pull_front(value_type& elem) = 0;
virtual void push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
};
template <typename ValueType, class SizeType>
class deque_base_copyable_and_movable
{
public:
typedef ValueType value_type;
typedef SizeType size_type;
// Constructors/Assignment/Destructors
virtual ~deque_base_copyable_and_movable() {};
// Observers
virtual bool empty() const = 0;
virtual bool full() const = 0;
virtual size_type size() const = 0;
virtual bool closed() const = 0;
// Modifiers
virtual void close() = 0;
virtual void push_back(const value_type& x) = 0;
virtual void pull_front(value_type&) = 0;
// enable_if is_nothrow_copy_movable<value_type>
virtual value_type pull_front() = 0;
virtual queue_op_status try_push_back(const value_type& x) = 0;
virtual queue_op_status try_pull_front(value_type&) = 0;
virtual queue_op_status nonblocking_push_back(const value_type& x) = 0;
virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
virtual queue_op_status wait_push_back(const value_type& x) = 0;
virtual queue_op_status wait_pull_front(value_type& elem) = 0;
virtual void push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
};
template <class T, class ST,
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined __GNUC__ && ! defined __clang__
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif // __GNUC__
#elif defined _MSC_VER
#if _MSC_VER < 1700
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif // _MSC_VER
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif
#else
bool Copyable = is_copy_constructible<T>::value,
bool Movable = has_move_emulation_enabled<T>::value
#endif
>
struct deque_base;
template <class T, class ST>
struct deque_base<T, ST, true, true> {
typedef deque_base_copyable_and_movable<T, ST> type;
};
template <class T, class ST>
struct deque_base<T, ST, true, false> {
typedef deque_base_copyable_only<T, ST> type;
};
template <class T, class ST>
struct deque_base<T, ST, false, true> {
typedef deque_base_movable_only<T, ST> type;
};
}
template <class ValueType, class SizeType=std::size_t>
class deque_base :
public detail::deque_base<ValueType, SizeType>::type
{
public:
typedef ValueType value_type;
typedef SizeType size_type;
// Constructors/Assignment/Destructors
virtual ~deque_base() {};
};
}
using concurrent::deque_base;
}
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,165 @@
#ifndef BOOST_THREAD_QUEUE_VIEWS_HPP
#define BOOST_THREAD_QUEUE_VIEWS_HPP
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 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/detail/move.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/thread/concurrent_queues/deque_base.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
template <typename Queue>
class deque_back_view
{
Queue* queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
deque_back_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
// Observers
bool empty() const { return queue->empty(); }
bool full() const { return queue->full(); }
size_type size() const { return queue->size(); }
bool closed() const { return queue->closed(); }
// Modifiers
void close() { queue->close(); }
void push(const value_type& x) { queue->push_back(x); }
void pull(value_type& x) { queue->pull_back(x); }
// enable_if is_nothrow_copy_movable<value_type>
value_type pull() { return queue->pull_back(); }
queue_op_status try_push(const value_type& x) { return queue->try_push_back(x); }
queue_op_status try_pull(value_type& x) { return queue->try_pull_back(x); }
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_back(x); }
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull_back(x); }
queue_op_status wait_push(const value_type& x) { return queue->wait_push_back(x); }
queue_op_status wait_pull(value_type& x) { return queue->wait_pull_back(x); }
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_back(boost::move(x)); }
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_back(boost::move(x)); }
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_back(boost::move(x)); }
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_back(boost::move(x)); }
};
template <typename Queue>
class deque_front_view
{
Queue* queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
deque_front_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
// Observers
bool empty() const { return queue->empty(); }
bool full() const { return queue->full(); }
size_type size() const { return queue->size(); }
bool closed() const { return queue->closed(); }
// Modifiers
void close() { queue->close(); }
void push(const value_type& x) { queue->push_front(x); }
void pull(value_type& x) { queue->pull_front(x); };
// enable_if is_nothrow_copy_movable<value_type>
value_type pull() { return queue->pull_front(); }
queue_op_status try_push(const value_type& x) { return queue->try_push_front(x); }
queue_op_status try_pull(value_type& x) { return queue->try_pull_front(x); }
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_front(x); }
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull_front(x); }
queue_op_status wait_push(const value_type& x) { return queue->wait_push_front(x); }
queue_op_status wait_pull(value_type& x) { return queue->wait_pull_front(x); }
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_front(forward<value_type>(x)); }
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_front(forward<value_type>(x)); }
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_front(forward<value_type>(x)); }
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_front(forward<value_type>(x)); }
};
#if ! defined BOOST_NO_CXX11_TEMPLATE_ALIASES
template <class T>
using deque_back = deque_back_view<deque_base<T> > ;
template <class T>
using deque_front = deque_front_view<deque_base<T> > ;
#else
template <class T>
struct deque_back : deque_back_view<deque_base<T> >
{
typedef deque_back_view<deque_base<T> > base_type;
deque_back(deque_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
};
template <class T>
struct deque_front : deque_front_view<deque_base<T> >
{
typedef deque_front_view<deque_base<T> > base_type;
deque_front(deque_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
};
#endif
// template <class Queue>
// deque_back_view<Queue> back(Queue & q) { return deque_back_view<Queue>(q); }
// template <class Queue>
// deque_front_view<Queue> front(Queue & q) { return deque_front_view<Queue>(q); }
//#if 0
// template <class T>
// deque_back<T> back(deque_base<T> & q) { return deque_back<T>(q); }
// template <class T>
// deque_front<T> front(deque_base<T> & q) { return deque_front<T>(q); }
//#else
// template <class T>
// typename deque_back<T>::type back(deque_base<T> & q) { return typename deque_back<T>::type(q); }
// template <class T>
// typename deque_front<T>::type front(deque_base<T> & q) { return typename deque_front<T>::type(q); }
//#endif
}
using concurrent::deque_back_view;
using concurrent::deque_front_view;
using concurrent::deque_back;
using concurrent::deque_front;
//using concurrent::back;
//using concurrent::front;
}
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,223 @@
#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 <boost/thread/detail/config.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/throw_exception.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
namespace detail
{
template <class ValueType, class Queue>
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 <typename Range>
//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<mutex> 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<mutex>& ) const BOOST_NOEXCEPT
{
return data_.empty();
}
inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return data_.empty();
}
inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return data_.size();
}
inline bool closed(unique_lock<mutex>& lk) const;
inline bool closed(lock_guard<mutex>& lk) const;
inline void throw_if_closed(unique_lock<mutex>&);
inline void throw_if_closed(lock_guard<mutex>&);
inline void wait_until_not_empty(unique_lock<mutex>& lk);
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
{
not_empty_.notify_one();
}
inline void notify_not_empty_if_needed(lock_guard<mutex>& )
{
not_empty_.notify_one();
}
};
template <class ValueType, class Queue>
sync_deque_base<ValueType, Queue>::sync_deque_base() :
data_(), closed_(false)
{
BOOST_ASSERT(data_.empty());
}
template <class ValueType, class Queue>
sync_deque_base<ValueType, Queue>::~sync_deque_base()
{
}
template <class ValueType, class Queue>
void sync_deque_base<ValueType, Queue>::close()
{
{
lock_guard<mutex> lk(mtx_);
closed_ = true;
}
not_empty_.notify_all();
}
template <class ValueType, class Queue>
bool sync_deque_base<ValueType, Queue>::closed() const
{
lock_guard<mutex> lk(mtx_);
return closed(lk);
}
template <class ValueType, class Queue>
bool sync_deque_base<ValueType, Queue>::closed(unique_lock<mutex>&) const
{
return closed_;
}
template <class ValueType, class Queue>
bool sync_deque_base<ValueType, Queue>::closed(lock_guard<mutex>&) const
{
return closed_;
}
template <class ValueType, class Queue>
bool sync_deque_base<ValueType, Queue>::empty() const
{
lock_guard<mutex> lk(mtx_);
return empty(lk);
}
template <class ValueType, class Queue>
bool sync_deque_base<ValueType, Queue>::full() const
{
return false;
}
template <class ValueType, class Queue>
typename sync_deque_base<ValueType, Queue>::size_type sync_deque_base<ValueType, Queue>::size() const
{
lock_guard<mutex> lk(mtx_);
return size(lk);
}
template <class ValueType, class Queue>
void sync_deque_base<ValueType, Queue>::throw_if_closed(unique_lock<mutex>& lk)
{
if (closed(lk))
{
BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
}
}
template <class ValueType, class Queue>
void sync_deque_base<ValueType, Queue>::throw_if_closed(lock_guard<mutex>& lk)
{
if (closed(lk))
{
BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
}
}
template <class ValueType, class Queue>
void sync_deque_base<ValueType, Queue>::wait_until_not_empty(unique_lock<mutex>& lk)
{
for (;;)
{
if (! empty(lk)) break;
throw_if_closed(lk);
not_empty_.wait(lk);
}
}
template <class ValueType, class Queue>
bool sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
{
for (;;)
{
if (! empty(lk)) break;
if (closed(lk)) return true;
not_empty_.wait(lk);
}
return false;
}
template <class ValueType, class Queue>
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& 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 <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,223 @@
#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-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/condition_variable.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/throw_exception.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
namespace detail
{
template <class ValueType, class Queue>
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;
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_queue_base)
inline sync_queue_base();
//template <typename Range>
//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<mutex> 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<mutex>& ) const BOOST_NOEXCEPT
{
return data_.empty();
}
inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return data_.empty();
}
inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return data_.size();
}
inline bool closed(unique_lock<mutex>& lk) const;
inline bool closed(lock_guard<mutex>& lk) const;
inline void throw_if_closed(unique_lock<mutex>&);
inline void throw_if_closed(lock_guard<mutex>&);
inline void wait_until_not_empty(unique_lock<mutex>& lk);
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
{
not_empty_.notify_one();
}
inline void notify_not_empty_if_needed(lock_guard<mutex>& )
{
not_empty_.notify_one();
}
};
template <class ValueType, class Queue>
sync_queue_base<ValueType, Queue>::sync_queue_base() :
data_(), closed_(false)
{
BOOST_ASSERT(data_.empty());
}
template <class ValueType, class Queue>
sync_queue_base<ValueType, Queue>::~sync_queue_base()
{
}
template <class ValueType, class Queue>
void sync_queue_base<ValueType, Queue>::close()
{
{
lock_guard<mutex> lk(mtx_);
closed_ = true;
}
not_empty_.notify_all();
}
template <class ValueType, class Queue>
bool sync_queue_base<ValueType, Queue>::closed() const
{
lock_guard<mutex> lk(mtx_);
return closed(lk);
}
template <class ValueType, class Queue>
bool sync_queue_base<ValueType, Queue>::closed(unique_lock<mutex>&) const
{
return closed_;
}
template <class ValueType, class Queue>
bool sync_queue_base<ValueType, Queue>::closed(lock_guard<mutex>&) const
{
return closed_;
}
template <class ValueType, class Queue>
bool sync_queue_base<ValueType, Queue>::empty() const
{
lock_guard<mutex> lk(mtx_);
return empty(lk);
}
template <class ValueType, class Queue>
bool sync_queue_base<ValueType, Queue>::full() const
{
return false;
}
template <class ValueType, class Queue>
typename sync_queue_base<ValueType, Queue>::size_type sync_queue_base<ValueType, Queue>::size() const
{
lock_guard<mutex> lk(mtx_);
return size(lk);
}
template <class ValueType, class Queue>
void sync_queue_base<ValueType, Queue>::throw_if_closed(unique_lock<mutex>& lk)
{
if (closed(lk))
{
BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
}
}
template <class ValueType, class Queue>
void sync_queue_base<ValueType, Queue>::throw_if_closed(lock_guard<mutex>& lk)
{
if (closed(lk))
{
BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
}
}
template <class ValueType, class Queue>
void sync_queue_base<ValueType, Queue>::wait_until_not_empty(unique_lock<mutex>& lk)
{
for (;;)
{
if (! empty(lk)) break;
throw_if_closed(lk);
not_empty_.wait(lk);
}
}
template <class ValueType, class Queue>
bool sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
{
for (;;)
{
if (! empty(lk)) break;
if (closed(lk)) return true;
not_empty_.wait(lk);
}
return false;
}
template <class ValueType, class Queue>
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& 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 <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,209 @@
#ifndef BOOST_THREAD_QUEUE_ADAPTOR_HPP
#define BOOST_THREAD_QUEUE_ADAPTOR_HPP
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 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/detail/move.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/thread/concurrent_queues/queue_base.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
namespace detail
{
template <typename Queue>
class queue_adaptor_copyable_only :
public boost::queue_base<typename Queue::value_type, typename Queue::size_type>
{
Queue queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
queue_adaptor_copyable_only() {}
// Observers
bool empty() const { return queue.empty(); }
bool full() const { return queue.full(); }
size_type size() const { return queue.size(); }
bool closed() const { return queue.closed(); }
// Modifiers
void close() { queue.close(); }
void push(const value_type& x) { queue.push(x); }
void pull(value_type& x) { queue.pull(x); };
value_type pull() { return queue.pull(); }
queue_op_status try_push(const value_type& x) { return queue.try_push(x); }
queue_op_status try_pull(value_type& x) { return queue.try_pull(x); }
queue_op_status nonblocking_push(const value_type& x) { return queue.nonblocking_push(x); }
queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); }
queue_op_status wait_push(const value_type& x) { return queue.wait_push(x); }
queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); }
};
template <typename Queue>
class queue_adaptor_movable_only :
public boost::queue_base<typename Queue::value_type, typename Queue::size_type>
{
Queue queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
queue_adaptor_movable_only() {}
// Observers
bool empty() const { return queue.empty(); }
bool full() const { return queue.full(); }
size_type size() const { return queue.size(); }
bool closed() const { return queue.closed(); }
// Modifiers
void close() { queue.close(); }
void pull(value_type& x) { queue.pull(x); };
// enable_if is_nothrow_copy_movable<value_type>
value_type pull() { return queue.pull(); }
queue_op_status try_pull(value_type& x) { return queue.try_pull(x); }
queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); }
queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); }
void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push(boost::move(x)); }
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push(boost::move(x)); }
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push(boost::move(x)); }
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push(boost::move(x)); }
};
template <typename Queue>
class queue_adaptor_copyable_and_movable :
public boost::queue_base<typename Queue::value_type, typename Queue::size_type>
{
Queue queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
queue_adaptor_copyable_and_movable() {}
// Observers
bool empty() const { return queue.empty(); }
bool full() const { return queue.full(); }
size_type size() const { return queue.size(); }
bool closed() const { return queue.closed(); }
// Modifiers
void close() { queue.close(); }
void push(const value_type& x) { queue.push(x); }
void pull(value_type& x) { queue.pull(x); };
// enable_if is_nothrow_copy_movable<value_type>
value_type pull() { return queue.pull(); }
queue_op_status try_push(const value_type& x) { return queue.try_push(x); }
queue_op_status try_pull(value_type& x) { return queue.try_pull(x); }
queue_op_status nonblocking_push(const value_type& x) { return queue.nonblocking_push(x); }
queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); }
queue_op_status wait_push(const value_type& x) { return queue.wait_push(x); }
queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); }
void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push(boost::move(x)); }
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push(boost::move(x)); }
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push(boost::move(x)); }
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push(boost::move(x)); }
};
template <class Q, class T,
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined __GNUC__ && ! defined __clang__
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif // __GNUC__
#elif defined _MSC_VER
#if _MSC_VER < 1700
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif // _MSC_VER
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif
#else
bool Copyable = is_copy_constructible<T>::value,
bool Movable = has_move_emulation_enabled<T>::value
#endif
>
struct queue_adaptor;
template <class Q, class T>
struct queue_adaptor<Q, T, true, true> {
typedef queue_adaptor_copyable_and_movable<Q> type;
};
template <class Q, class T>
struct queue_adaptor<Q, T, true, false> {
typedef queue_adaptor_copyable_only<Q> type;
};
template <class Q, class T>
struct queue_adaptor<Q, T, false, true> {
typedef queue_adaptor_movable_only<Q> type;
};
}
template <typename Queue>
class queue_adaptor :
public detail::queue_adaptor<Queue, typename Queue::value_type>::type
{
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
virtual ~queue_adaptor() {};
};
}
using concurrent::queue_adaptor;
}
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,202 @@
#ifndef BOOST_THREAD_QUEUE_BASE_HPP
#define BOOST_THREAD_QUEUE_BASE_HPP
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 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/detail/move.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
namespace detail
{
template <typename ValueType, class SizeType>
class queue_base_copyable_only
{
public:
typedef ValueType value_type;
typedef SizeType size_type;
// Constructors/Assignment/Destructors
virtual ~queue_base_copyable_only() {};
// Observers
virtual bool empty() const = 0;
virtual bool full() const = 0;
virtual size_type size() const = 0;
virtual bool closed() const = 0;
// Modifiers
virtual void close() = 0;
virtual void push(const value_type& x) = 0;
virtual void pull(value_type&) = 0;
virtual value_type pull() = 0;
virtual queue_op_status try_push(const value_type& x) = 0;
virtual queue_op_status try_pull(value_type&) = 0;
virtual queue_op_status nonblocking_push(const value_type& x) = 0;
virtual queue_op_status nonblocking_pull(value_type&) = 0;
virtual queue_op_status wait_push(const value_type& x) = 0;
virtual queue_op_status wait_pull(ValueType& elem) = 0;
};
template <typename ValueType, class SizeType>
class queue_base_movable_only
{
public:
typedef ValueType value_type;
typedef SizeType size_type;
// Constructors/Assignment/Destructors
virtual ~queue_base_movable_only() {};
// Observers
virtual bool empty() const = 0;
virtual bool full() const = 0;
virtual size_type size() const = 0;
virtual bool closed() const = 0;
// Modifiers
virtual void close() = 0;
virtual void pull(value_type&) = 0;
// enable_if is_nothrow_movable<value_type>
virtual value_type pull() = 0;
virtual queue_op_status try_pull(value_type&) = 0;
virtual queue_op_status nonblocking_pull(value_type&) = 0;
virtual queue_op_status wait_pull(value_type& elem) = 0;
virtual void push(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
};
template <typename ValueType, class SizeType>
class queue_base_copyable_and_movable
{
public:
typedef ValueType value_type;
typedef SizeType size_type;
// Constructors/Assignment/Destructors
virtual ~queue_base_copyable_and_movable() {};
// Observers
virtual bool empty() const = 0;
virtual bool full() const = 0;
virtual size_type size() const = 0;
virtual bool closed() const = 0;
// Modifiers
virtual void close() = 0;
virtual void push(const value_type& x) = 0;
virtual void pull(value_type&) = 0;
// enable_if is_nothrow_copy_movable<value_type>
virtual value_type pull() = 0;
virtual queue_op_status try_push(const value_type& x) = 0;
virtual queue_op_status try_pull(value_type&) = 0;
virtual queue_op_status nonblocking_push(const value_type& x) = 0;
virtual queue_op_status nonblocking_pull(value_type&) = 0;
virtual queue_op_status wait_push(const value_type& x) = 0;
virtual queue_op_status wait_pull(value_type& elem) = 0;
virtual void push(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
virtual queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
};
template <class T, class ST,
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined __GNUC__ && ! defined __clang__
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif // __GNUC__
#elif defined _MSC_VER
#if _MSC_VER < 1700
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif // _MSC_VER
#else
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
#endif
#else
bool Copyable = is_copy_constructible<T>::value,
bool Movable = has_move_emulation_enabled<T>::value
#endif
>
struct queue_base;
template <class T, class ST>
struct queue_base<T, ST, true, true> {
typedef queue_base_copyable_and_movable<T, ST> type;
};
template <class T, class ST>
struct queue_base<T, ST, true, false> {
typedef queue_base_copyable_only<T, ST> type;
};
template <class T, class ST>
struct queue_base<T, ST, false, true> {
typedef queue_base_movable_only<T, ST> type;
};
}
template <typename ValueType, class SizeType=std::size_t>
class queue_base :
public detail::queue_base<ValueType, SizeType>::type
{
public:
typedef ValueType value_type;
typedef SizeType size_type;
// Constructors/Assignment/Destructors
virtual ~queue_base() {};
};
}
using concurrent::queue_base;
}
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,46 @@
#ifndef BOOST_THREAD_QUEUE_OP_STATUS_HPP
#define BOOST_THREAD_QUEUE_OP_STATUS_HPP
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 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/detail/move.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
BOOST_SCOPED_ENUM_DECLARE_BEGIN(queue_op_status)
{ success = 0, empty, full, closed, busy, timeout, not_ready }
BOOST_SCOPED_ENUM_DECLARE_END(queue_op_status)
struct sync_queue_is_closed : std::exception
{
};
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
struct no_block_tag{};
BOOST_CONSTEXPR_OR_CONST no_block_tag no_block = {};
#endif
using concurrent::queue_op_status;
using concurrent::sync_queue_is_closed;
}
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,144 @@
#ifndef BOOST_THREAD_QUEUE_VIEWS_HPP
#define BOOST_THREAD_QUEUE_VIEWS_HPP
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 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/detail/move.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/thread/concurrent_queues/queue_base.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
template <typename Queue>
class queue_back_view
{
Queue* queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
queue_back_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
// Observers
bool empty() const { return queue->empty(); }
bool full() const { return queue->full(); }
size_type size() const { return queue->size(); }
bool closed() const { return queue->closed(); }
// Modifiers
void close() { queue->close(); }
void push(const value_type& x) { queue->push(x); }
queue_op_status try_push(const value_type& x) { return queue->try_push(x); }
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push(x); }
queue_op_status wait_push(const value_type& x) { return queue->wait_push(x); }
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push(boost::move(x)); }
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push(boost::move(x)); }
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push(boost::move(x)); }
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push(boost::move(x)); }
};
template <typename Queue>
class queue_front_view
{
Queue* queue;
public:
typedef typename Queue::value_type value_type;
typedef typename Queue::size_type size_type;
// Constructors/Assignment/Destructors
queue_front_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
// Observers
bool empty() const { return queue->empty(); }
bool full() const { return queue->full(); }
size_type size() const { return queue->size(); }
bool closed() const { return queue->closed(); }
// Modifiers
void close() { queue->close(); }
void pull(value_type& x) { queue->pull(x); };
// enable_if is_nothrow_copy_movable<value_type>
value_type pull() { return queue->pull(); }
queue_op_status try_pull(value_type& x) { return queue->try_pull(x); }
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull(x); }
queue_op_status wait_pull(value_type& x) { return queue->wait_pull(x); }
};
#if ! defined BOOST_NO_CXX11_TEMPLATE_ALIASES
template <class T>
using queue_back = queue_back_view<queue_base<T> > ;
template <class T>
using queue_front = queue_front_view<queue_base<T> > ;
#else
template <class T>
struct queue_back : queue_back_view<queue_base<T> >
{
typedef queue_back_view<queue_base<T> > base_type;
queue_back(queue_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
};
template <class T>
struct queue_front : queue_front_view<queue_base<T> >
{
typedef queue_front_view<queue_base<T> > base_type;
queue_front(queue_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
};
#endif
// template <class Queue>
// queue_back_view<Queue> back(Queue & q) { return queue_back_view<Queue>(q); }
// template <class Queue>
// queue_front_view<Queue> front(Queue & q) { return queue_front_view<Queue>(q); }
//#if 0
// template <class T>
// queue_back<T> back(queue_base<T> & q) { return queue_back<T>(q); }
// template <class T>
// queue_front<T> front(queue_base<T> & q) { return queue_front<T>(q); }
//#else
// template <class T>
// typename queue_back<T>::type back(queue_base<T> & q) { return typename queue_back<T>::type(q); }
// template <class T>
// typename queue_front<T>::type front(queue_base<T> & q) { return typename queue_front<T>::type(q); }
//#endif
}
using concurrent::queue_back_view;
using concurrent::queue_front_view;
using concurrent::queue_back;
using concurrent::queue_front;
//using concurrent::back;
//using concurrent::front;
}
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,725 @@
#ifndef BOOST_THREAD_CONCURRENT_QUEUES_SYNC_BOUNDED_QUEUE_HPP
#define BOOST_THREAD_CONCURRENT_QUEUES_SYNC_BOUNDED_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/condition_variable.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/throw_exception.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#endif
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
template <typename ValueType>
class sync_bounded_queue
{
public:
typedef ValueType value_type;
typedef std::size_t size_type;
// Constructors/Assignment/Destructors
BOOST_THREAD_NO_COPYABLE(sync_bounded_queue)
explicit sync_bounded_queue(size_type max_elems);
template <typename Range>
sync_bounded_queue(size_type max_elems, Range range);
~sync_bounded_queue();
// Observers
inline bool empty() const;
inline bool full() const;
inline size_type capacity() const;
inline size_type size() const;
inline bool closed() const;
// Modifiers
inline void close();
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
inline void push(const value_type& x);
inline void push(BOOST_THREAD_RV_REF(value_type) x);
inline bool try_push(const value_type& x);
inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
inline bool try_push(no_block_tag, const value_type& x);
inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
#endif
inline void push_back(const value_type& x);
inline void push_back(BOOST_THREAD_RV_REF(value_type) x);
inline queue_op_status try_push_back(const value_type& x);
inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x);
inline queue_op_status nonblocking_push_back(const value_type& x);
inline queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x);
inline queue_op_status wait_push_back(const value_type& x);
inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x);
// Observers/Modifiers
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
inline void pull(value_type&);
// enable_if is_nothrow_copy_movable<value_type>
inline value_type pull();
inline shared_ptr<ValueType> ptr_pull();
inline bool try_pull(value_type&);
inline bool try_pull(no_block_tag,value_type&);
inline shared_ptr<ValueType> try_pull();
#endif
inline void pull_front(value_type&);
// enable_if is_nothrow_copy_movable<value_type>
inline value_type pull_front();
inline queue_op_status try_pull_front(value_type&);
inline queue_op_status nonblocking_pull_front(value_type&);
inline queue_op_status wait_pull_front(ValueType& elem);
private:
mutable mutex mtx_;
condition_variable not_empty_;
condition_variable not_full_;
size_type waiting_full_;
size_type waiting_empty_;
value_type* data_;
size_type in_;
size_type out_;
size_type capacity_;
bool closed_;
inline size_type inc(size_type idx) const BOOST_NOEXCEPT
{
return (idx + 1) % capacity_;
}
inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
{
return in_ == out_;
}
inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return in_ == out_;
}
inline bool full(unique_lock<mutex>& ) const BOOST_NOEXCEPT
{
return (inc(in_) == out_);
}
inline bool full(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return (inc(in_) == out_);
}
inline size_type capacity(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return capacity_-1;
}
inline size_type size(lock_guard<mutex>& lk) const BOOST_NOEXCEPT
{
if (full(lk)) return capacity(lk);
return ((out_+capacity(lk)-in_) % capacity(lk));
}
inline void throw_if_closed(unique_lock<mutex>&);
inline bool closed(unique_lock<mutex>&) const;
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
#endif
inline queue_op_status try_pull_front(value_type& x, unique_lock<mutex>& lk);
inline queue_op_status try_push_back(const value_type& x, unique_lock<mutex>& lk);
inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
inline queue_op_status wait_pull_front(value_type& x, unique_lock<mutex>& lk);
inline queue_op_status wait_push_back(const value_type& x, unique_lock<mutex>& lk);
inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
inline void wait_until_not_empty(unique_lock<mutex>& lk);
inline void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
inline size_type wait_until_not_full(unique_lock<mutex>& lk);
inline size_type wait_until_not_full(unique_lock<mutex>& lk, bool&);
inline void notify_not_empty_if_needed(unique_lock<mutex>& lk)
{
if (waiting_empty_ > 0)
{
--waiting_empty_;
lk.unlock();
not_empty_.notify_one();
}
}
inline void notify_not_full_if_needed(unique_lock<mutex>& lk)
{
if (waiting_full_ > 0)
{
--waiting_full_;
lk.unlock();
not_full_.notify_one();
}
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
inline void pull(value_type& elem, unique_lock<mutex>& lk)
{
elem = boost::move(data_[out_]);
out_ = inc(out_);
notify_not_full_if_needed(lk);
}
inline value_type pull(unique_lock<mutex>& lk)
{
value_type elem = boost::move(data_[out_]);
out_ = inc(out_);
notify_not_full_if_needed(lk);
return boost::move(elem);
}
inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& lk)
{
shared_ptr<value_type> res = make_shared<value_type>(boost::move(data_[out_]));
out_ = inc(out_);
notify_not_full_if_needed(lk);
return res;
}
#endif
inline void pull_front(value_type& elem, unique_lock<mutex>& lk)
{
elem = boost::move(data_[out_]);
out_ = inc(out_);
notify_not_full_if_needed(lk);
}
inline value_type pull_front(unique_lock<mutex>& lk)
{
value_type elem = boost::move(data_[out_]);
out_ = inc(out_);
notify_not_full_if_needed(lk);
return boost::move(elem);
}
inline void set_in(size_type in, unique_lock<mutex>& lk)
{
in_ = in;
notify_not_empty_if_needed(lk);
}
inline void push_at(const value_type& elem, size_type in_p_1, unique_lock<mutex>& lk)
{
data_[in_] = elem;
set_in(in_p_1, lk);
}
inline void push_at(BOOST_THREAD_RV_REF(value_type) elem, size_type in_p_1, unique_lock<mutex>& lk)
{
data_[in_] = boost::move(elem);
set_in(in_p_1, lk);
}
};
template <typename ValueType>
sync_bounded_queue<ValueType>::sync_bounded_queue(typename sync_bounded_queue<ValueType>::size_type max_elems) :
waiting_full_(0), waiting_empty_(0), data_(new value_type[max_elems + 1]), in_(0), out_(0), capacity_(max_elems + 1),
closed_(false)
{
BOOST_ASSERT_MSG(max_elems >= 1, "number of elements must be > 1");
}
// template <typename ValueType>
// template <typename Range>
// sync_bounded_queue<ValueType>::sync_bounded_queue(size_type max_elems, Range range) :
// waiting_full_(0), waiting_empty_(0), data_(new value_type[max_elems + 1]), in_(0), out_(0), capacity_(max_elems + 1),
// closed_(false)
// {
// BOOST_ASSERT_MSG(max_elems >= 1, "number of elements must be > 1");
// BOOST_ASSERT_MSG(max_elems == size(range), "number of elements must match range's size");
// try
// {
// typedef typename Range::iterator iterator_t;
// iterator_t first = boost::begin(range);
// iterator_t end = boost::end(range);
// size_type in = 0;
// for (iterator_t cur = first; cur != end; ++cur, ++in)
// {
// data_[in] = *cur;
// }
// set_in(in);
// }
// catch (...)
// {
// delete[] data_;
// }
// }
template <typename ValueType>
sync_bounded_queue<ValueType>::~sync_bounded_queue()
{
delete[] data_;
}
template <typename ValueType>
void sync_bounded_queue<ValueType>::close()
{
{
lock_guard<mutex> lk(mtx_);
closed_ = true;
}
not_empty_.notify_all();
not_full_.notify_all();
}
template <typename ValueType>
bool sync_bounded_queue<ValueType>::closed() const
{
lock_guard<mutex> lk(mtx_);
return closed_;
}
template <typename ValueType>
bool sync_bounded_queue<ValueType>::closed(unique_lock<mutex>& ) const
{
return closed_;
}
template <typename ValueType>
bool sync_bounded_queue<ValueType>::empty() const
{
lock_guard<mutex> lk(mtx_);
return empty(lk);
}
template <typename ValueType>
bool sync_bounded_queue<ValueType>::full() const
{
lock_guard<mutex> lk(mtx_);
return full(lk);
}
template <typename ValueType>
typename sync_bounded_queue<ValueType>::size_type sync_bounded_queue<ValueType>::capacity() const
{
lock_guard<mutex> lk(mtx_);
return capacity(lk);
}
template <typename ValueType>
typename sync_bounded_queue<ValueType>::size_type sync_bounded_queue<ValueType>::size() const
{
lock_guard<mutex> lk(mtx_);
return size(lk);
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
template <typename ValueType>
bool sync_bounded_queue<ValueType>::try_pull(ValueType& elem, unique_lock<mutex>& lk)
{
if (empty(lk))
{
throw_if_closed(lk);
return false;
}
pull(elem, lk);
return true;
}
template <typename ValueType>
shared_ptr<ValueType> sync_bounded_queue<ValueType>::try_pull(unique_lock<mutex>& lk)
{
if (empty(lk))
{
throw_if_closed(lk);
return shared_ptr<ValueType>();
}
return ptr_pull(lk);
}
template <typename ValueType>
bool sync_bounded_queue<ValueType>::try_pull(ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
return try_pull(elem, lk);
}
#endif
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::try_pull_front(ValueType& elem, unique_lock<mutex>& lk)
{
if (empty(lk))
{
if (closed(lk)) return queue_op_status::closed;
return queue_op_status::empty;
}
pull_front(elem, lk);
return queue_op_status::success;
}
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::try_pull_front(ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
return try_pull_front(elem, lk);
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
template <typename ValueType>
bool sync_bounded_queue<ValueType>::try_pull(no_block_tag,ValueType& elem)
{
unique_lock<mutex> lk(mtx_, try_to_lock);
if (!lk.owns_lock())
{
return false;
}
return try_pull(elem, lk);
}
template <typename ValueType>
boost::shared_ptr<ValueType> sync_bounded_queue<ValueType>::try_pull()
{
unique_lock<mutex> lk(mtx_);
return try_pull(lk);
}
#endif
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::nonblocking_pull_front(ValueType& elem)
{
unique_lock<mutex> lk(mtx_, try_to_lock);
if (!lk.owns_lock())
{
return queue_op_status::busy;
}
return try_pull_front(elem, lk);
}
template <typename ValueType>
void sync_bounded_queue<ValueType>::throw_if_closed(unique_lock<mutex>&)
{
if (closed_)
{
BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
}
}
template <typename ValueType>
void sync_bounded_queue<ValueType>::wait_until_not_empty(unique_lock<mutex>& lk)
{
for (;;)
{
if (out_ != in_) break;
throw_if_closed(lk);
++waiting_empty_;
not_empty_.wait(lk);
}
}
template <typename ValueType>
void sync_bounded_queue<ValueType>::wait_until_not_empty(unique_lock<mutex>& lk, bool & closed)
{
for (;;)
{
if (out_ != in_) break;
if (closed_) {closed=true; return;}
++waiting_empty_;
not_empty_.wait(lk);
}
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
template <typename ValueType>
void sync_bounded_queue<ValueType>::pull(ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
wait_until_not_empty(lk);
pull(elem, lk);
}
// template <typename ValueType>
// void sync_bounded_queue<ValueType>::pull(ValueType& elem, bool & closed)
// {
// unique_lock<mutex> lk(mtx_);
// wait_until_not_empty(lk, closed);
// if (closed) {return;}
// pull(elem, lk);
// }
// enable if ValueType is nothrow movable
template <typename ValueType>
ValueType sync_bounded_queue<ValueType>::pull()
{
unique_lock<mutex> lk(mtx_);
wait_until_not_empty(lk);
return pull(lk);
}
template <typename ValueType>
boost::shared_ptr<ValueType> sync_bounded_queue<ValueType>::ptr_pull()
{
unique_lock<mutex> lk(mtx_);
wait_until_not_empty(lk);
return ptr_pull(lk);
}
#endif
template <typename ValueType>
void sync_bounded_queue<ValueType>::pull_front(ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
wait_until_not_empty(lk);
pull_front(elem, lk);
}
// enable if ValueType is nothrow movable
template <typename ValueType>
ValueType sync_bounded_queue<ValueType>::pull_front()
{
unique_lock<mutex> lk(mtx_);
wait_until_not_empty(lk);
return pull_front(lk);
}
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::wait_pull_front(ValueType& elem, unique_lock<mutex>& lk)
{
if (empty(lk) && closed(lk)) {return queue_op_status::closed;}
wait_until_not_empty(lk);
pull_front(elem, lk);
return queue_op_status::success;
}
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::wait_pull_front(ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
return wait_pull_front(elem, lk);
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
template <typename ValueType>
bool sync_bounded_queue<ValueType>::try_push(const ValueType& elem, unique_lock<mutex>& lk)
{
throw_if_closed(lk);
size_type in_p_1 = inc(in_);
if (in_p_1 == out_) // full()
{
return false;
}
push_at(elem, in_p_1, lk);
return true;
}
template <typename ValueType>
bool sync_bounded_queue<ValueType>::try_push(const ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
return try_push(elem, lk);
}
#endif
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::try_push_back(const ValueType& elem, unique_lock<mutex>& lk)
{
if (closed(lk)) return queue_op_status::closed;
size_type in_p_1 = inc(in_);
if (in_p_1 == out_) // full()
{
return queue_op_status::full;
}
push_at(elem, in_p_1, lk);
return queue_op_status::success;
}
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::try_push_back(const ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
return try_push_back(elem, lk);
}
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::wait_push_back(const ValueType& elem, unique_lock<mutex>& lk)
{
if (closed(lk)) return queue_op_status::closed;
push_at(elem, wait_until_not_full(lk), lk);
return queue_op_status::success;
}
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::wait_push_back(const ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
return wait_push_back(elem, lk);
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
template <typename ValueType>
bool sync_bounded_queue<ValueType>::try_push(no_block_tag, const ValueType& elem)
{
unique_lock<mutex> lk(mtx_, try_to_lock);
if (!lk.owns_lock()) return false;
return try_push(elem, lk);
}
#endif
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::nonblocking_push_back(const ValueType& elem)
{
unique_lock<mutex> lk(mtx_, try_to_lock);
if (!lk.owns_lock()) return queue_op_status::busy;
return try_push_back(elem, lk);
}
template <typename ValueType>
typename sync_bounded_queue<ValueType>::size_type sync_bounded_queue<ValueType>::wait_until_not_full(unique_lock<mutex>& lk)
{
for (;;)
{
throw_if_closed(lk);
size_type in_p_1 = inc(in_);
if (in_p_1 != out_) // ! full()
{
return in_p_1;
}
++waiting_full_;
not_full_.wait(lk);
}
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
template <typename ValueType>
void sync_bounded_queue<ValueType>::push(const ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
push_at(elem, wait_until_not_full(lk), lk);
}
#endif
template <typename ValueType>
void sync_bounded_queue<ValueType>::push_back(const ValueType& elem)
{
unique_lock<mutex> lk(mtx_);
push_at(elem, wait_until_not_full(lk), lk);
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
template <typename ValueType>
bool sync_bounded_queue<ValueType>::try_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
{
throw_if_closed(lk);
size_type in_p_1 = inc(in_);
if (in_p_1 == out_) // full()
{
return false;
}
push_at(boost::move(elem), in_p_1, lk);
return true;
}
template <typename ValueType>
bool sync_bounded_queue<ValueType>::try_push(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(mtx_);
return try_push(boost::move(elem), lk);
}
#endif
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
{
if (closed(lk)) return queue_op_status::closed;
size_type in_p_1 = inc(in_);
if (in_p_1 == out_) // full()
{
return queue_op_status::full;
}
push_at(boost::move(elem), in_p_1, lk);
return queue_op_status::success;
}
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(mtx_);
return try_push_back(boost::move(elem), lk);
}
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
{
if (closed(lk)) return queue_op_status::closed;
push_at(boost::move(elem), wait_until_not_full(lk), lk);
return queue_op_status::success;
}
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(mtx_);
return try_push_back(boost::move(elem), lk);
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
template <typename ValueType>
bool sync_bounded_queue<ValueType>::try_push(no_block_tag, BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(mtx_, try_to_lock);
if (!lk.owns_lock())
{
return false;
}
return try_push(boost::move(elem), lk);
}
#endif
template <typename ValueType>
queue_op_status sync_bounded_queue<ValueType>::nonblocking_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(mtx_, try_to_lock);
if (!lk.owns_lock())
{
return queue_op_status::busy;
}
return try_push_back(boost::move(elem), lk);
}
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
template <typename ValueType>
void sync_bounded_queue<ValueType>::push(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(mtx_);
push_at(boost::move(elem), wait_until_not_full(lk), lk);
}
#endif
template <typename ValueType>
void sync_bounded_queue<ValueType>::push_back(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(mtx_);
push_at(boost::move(elem), wait_until_not_full(lk), lk);
}
template <typename ValueType>
sync_bounded_queue<ValueType>& operator<<(sync_bounded_queue<ValueType>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
{
sbq.push_back(boost::move(elem));
return sbq;
}
template <typename ValueType>
sync_bounded_queue<ValueType>& operator<<(sync_bounded_queue<ValueType>& sbq, ValueType const&elem)
{
sbq.push_back(elem);
return sbq;
}
template <typename ValueType>
sync_bounded_queue<ValueType>& operator>>(sync_bounded_queue<ValueType>& sbq, ValueType &elem)
{
sbq.pull_front(elem);
return sbq;
}
}
using concurrent::sync_bounded_queue;
}
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,327 @@
#ifndef BOOST_THREAD_CONCURRENT_QUEUES_SYNC_DEQUE_HPP
#define BOOST_THREAD_CONCURRENT_QUEUES_SYNC_DEQUE_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_deque
: 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_deque)
inline sync_deque();
//template <typename Range>
//inline explicit sync_deque(Range range);
inline ~sync_deque();
// Modifiers
inline void push_back(const value_type& x);
inline queue_op_status try_push_back(const value_type& x);
inline queue_op_status nonblocking_push_back(const value_type& x);
inline queue_op_status wait_push_back(const value_type& x);
inline void push_back(BOOST_THREAD_RV_REF(value_type) x);
inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x);
inline queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x);
inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x);
// Observers/Modifiers
inline void pull_front(value_type&);
// enable_if is_nothrow_copy_movable<value_type>
inline value_type pull_front();
inline queue_op_status try_pull_front(value_type&);
inline queue_op_status nonblocking_pull_front(value_type&);
inline queue_op_status wait_pull_front(ValueType& elem);
private:
inline queue_op_status try_pull_front(value_type& x, unique_lock<mutex>& lk);
inline queue_op_status wait_pull_front(value_type& x, unique_lock<mutex>& lk);
inline queue_op_status try_push_back(const value_type& x, unique_lock<mutex>& lk);
inline queue_op_status wait_push_back(const value_type& x, unique_lock<mutex>& lk);
inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
inline void pull_front(value_type& elem, unique_lock<mutex>& )
{
elem = boost::move(super::data_.front());
super::data_.pop_front();
}
inline value_type pull_front(unique_lock<mutex>& )
{
value_type e = boost::move(super::data_.front());
super::data_.pop_front();
return boost::move(e);
}
inline void push_back(const value_type& elem, unique_lock<mutex>& lk)
{
super::data_.push_back(elem);
super::notify_not_empty_if_needed(lk);
}
inline void push_back(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_deque<ValueType, Container>::sync_deque() :
super()
{
}
// template <class ValueType, class Container>
// template <class Range>
// explicit sync_deque<ValueType, Container>::sync_deque(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_deque<ValueType, Container>::~sync_deque()
{
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::try_pull_front(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_front(elem, lk);
return queue_op_status::success;
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::wait_pull_front(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_front(elem, lk);
return queue_op_status::success;
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::try_pull_front(ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_);
return try_pull_front(elem, lk);
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::wait_pull_front(ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_);
return wait_pull_front(elem, lk);
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::nonblocking_pull_front(ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_, try_to_lock);
if (!lk.owns_lock())
{
return queue_op_status::busy;
}
return try_pull_front(elem, lk);
}
template <class ValueType, class Container>
void sync_deque<ValueType, Container>::pull_front(ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
pull_front(elem, lk);
}
// enable if ValueType is nothrow movable
template <class ValueType, class Container>
ValueType sync_deque<ValueType, Container>::pull_front()
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
return pull_front(lk);
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::try_push_back(const ValueType& elem, unique_lock<mutex>& lk)
{
if (super::closed(lk)) return queue_op_status::closed;
push_back(elem, lk);
return queue_op_status::success;
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::try_push_back(const ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_);
return try_push_back(elem, lk);
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::wait_push_back(const ValueType& elem, unique_lock<mutex>& lk)
{
if (super::closed(lk)) return queue_op_status::closed;
push_back(elem, lk);
return queue_op_status::success;
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::wait_push_back(const ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_);
return wait_push_back(elem, lk);
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::nonblocking_push_back(const ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_, try_to_lock);
if (!lk.owns_lock()) return queue_op_status::busy;
return try_push_back(elem, lk);
}
template <class ValueType, class Container>
void sync_deque<ValueType, Container>::push_back(const ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_);
super::throw_if_closed(lk);
push_back(elem, lk);
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
{
if (super::closed(lk)) return queue_op_status::closed;
push_back(boost::move(elem), lk);
return queue_op_status::success;
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(super::mtx_);
return try_push_back(boost::move(elem), lk);
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
{
if (super::closed(lk)) return queue_op_status::closed;
push_back(boost::move(elem), lk);
return queue_op_status::success;
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(super::mtx_);
return wait_push_back(boost::move(elem), lk);
}
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::nonblocking_push_back(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_back(boost::move(elem), lk);
}
template <class ValueType, class Container>
void sync_deque<ValueType, Container>::push_back(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(super::mtx_);
super::throw_if_closed(lk);
push_back(boost::move(elem), lk);
}
template <class ValueType, class Container>
sync_deque<ValueType, Container>& operator<<(sync_deque<ValueType, Container>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
{
sbq.push_back(boost::move(elem));
return sbq;
}
template <class ValueType, class Container>
sync_deque<ValueType, Container>& operator<<(sync_deque<ValueType, Container>& sbq, ValueType const&elem)
{
sbq.push_back(elem);
return sbq;
}
template <class ValueType, class Container>
sync_deque<ValueType, Container>& operator>>(sync_deque<ValueType, Container>& sbq, ValueType &elem)
{
sbq.pull_front(elem);
return sbq;
}
}
using concurrent::sync_deque;
}
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,369 @@
// Copyright (C) 2014 Ian Forbed
// Copyright (C) 2014 Vicente J. Botet Escriba
//
// 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)
//
#ifndef BOOST_THREAD_SYNC_PRIORITY_QUEUE
#define BOOST_THREAD_SYNC_PRIORITY_QUEUE
#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/vector.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/atomic.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <exception>
#include <queue>
#include <utility>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace detail {
template <
class Type,
class Container = csbl::vector<Type>,
class Compare = std::less<Type>
>
class priority_queue
{
private:
Container _elements;
Compare _compare;
public:
typedef Type value_type;
typedef typename Container::size_type size_type;
explicit priority_queue(const Compare& compare = Compare())
: _elements(), _compare(compare)
{ }
size_type size() const
{
return _elements.size();
}
bool empty() const
{
return _elements.empty();
}
void push(Type const& element)
{
_elements.push_back(element);
std::push_heap(_elements.begin(), _elements.end(), _compare);
}
void push(BOOST_RV_REF(Type) element)
{
_elements.push_back(boost::move(element));
std::push_heap(_elements.begin(), _elements.end(), _compare);
}
void pop()
{
std::pop_heap(_elements.begin(), _elements.end(), _compare);
_elements.pop_back();
}
Type pull()
{
Type result = boost::move(_elements.front());
pop();
return boost::move(result);
}
Type const& top()
{
return _elements.front();
}
};
}
namespace concurrent
{
template <class ValueType,
class Container = csbl::vector<ValueType>,
class Compare = std::less<typename Container::value_type> >
class sync_priority_queue
: public detail::sync_queue_base<ValueType, boost::detail::priority_queue<ValueType,Container,Compare> >
{
typedef detail::sync_queue_base<ValueType, boost::detail::priority_queue<ValueType,Container,Compare> > 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;
typedef chrono::steady_clock clock;
protected:
public:
sync_priority_queue() {}
~sync_priority_queue()
{
if(!super::closed())
{
super::close();
}
}
void push(const ValueType& elem);
void push(BOOST_THREAD_RV_REF(ValueType) elem);
queue_op_status try_push(const ValueType& elem);
queue_op_status try_push(BOOST_THREAD_RV_REF(ValueType) elem);
ValueType pull();
void pull(ValueType&);
queue_op_status pull_until(const clock::time_point&, ValueType&);
queue_op_status pull_for(const clock::duration&, ValueType&);
queue_op_status try_pull(ValueType& elem);
queue_op_status wait_pull(ValueType& elem);
queue_op_status nonblocking_pull(ValueType&);
private:
void push(unique_lock<mutex>&, const ValueType& elem);
void push(lock_guard<mutex>&, const ValueType& elem);
void push(unique_lock<mutex>&, BOOST_THREAD_RV_REF(ValueType) elem);
void push(lock_guard<mutex>&, BOOST_THREAD_RV_REF(ValueType) elem);
queue_op_status try_push(unique_lock<mutex>&, const ValueType& elem);
queue_op_status try_push(unique_lock<mutex>&, BOOST_THREAD_RV_REF(ValueType) elem);
ValueType pull(unique_lock<mutex>&);
ValueType pull(lock_guard<mutex>&);
void pull(unique_lock<mutex>&, ValueType&);
void pull(lock_guard<mutex>&, ValueType&);
queue_op_status try_pull(lock_guard<mutex>& lk, ValueType& elem);
queue_op_status try_pull(unique_lock<mutex>& lk, ValueType& elem);
queue_op_status wait_pull(unique_lock<mutex>& lk, ValueType& elem);
queue_op_status nonblocking_pull(unique_lock<mutex>& lk, ValueType&);
sync_priority_queue(const sync_priority_queue&);
sync_priority_queue& operator= (const sync_priority_queue&);
sync_priority_queue(BOOST_THREAD_RV_REF(sync_priority_queue));
sync_priority_queue& operator= (BOOST_THREAD_RV_REF(sync_priority_queue));
}; //end class
//////////////////////
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(unique_lock<mutex>& lk, const T& elem)
{
super::throw_if_closed(lk);
super::data_.push(elem);
super::notify_not_empty_if_needed(lk);
}
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, const T& elem)
{
super::throw_if_closed(lk);
super::data_.push(elem);
super::notify_not_empty_if_needed(lk);
}
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(const T& elem)
{
lock_guard<mutex> lk(super::mtx_);
push(lk, elem);
}
//////////////////////
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(unique_lock<mutex>& lk, BOOST_THREAD_RV_REF(T) elem)
{
super::throw_if_closed(lk);
super::data_.push(boost::move(elem));
super::notify_not_empty_if_needed(lk);
}
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, BOOST_THREAD_RV_REF(T) elem)
{
super::throw_if_closed(lk);
super::data_.push(boost::move(elem));
super::notify_not_empty_if_needed(lk);
}
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(BOOST_THREAD_RV_REF(T) elem)
{
lock_guard<mutex> lk(super::mtx_);
push(lk, boost::move(elem));
}
//////////////////////
template <class T, class Container,class Cmp>
queue_op_status sync_priority_queue<T,Container,Cmp>::try_push(const T& elem)
{
lock_guard<mutex> lk(super::mtx_);
if (super::closed(lk)) return queue_op_status::closed;
push(lk, elem);
return queue_op_status::success;
}
//////////////////////
template <class T, class Container,class Cmp>
queue_op_status sync_priority_queue<T,Container,Cmp>::try_push(BOOST_THREAD_RV_REF(T) elem)
{
lock_guard<mutex> lk(super::mtx_);
if (super::closed(lk)) return queue_op_status::closed;
push(lk, boost::move(elem));
return queue_op_status::success;
}
//////////////////////
template <class T,class Container, class Cmp>
T sync_priority_queue<T,Container,Cmp>::pull(unique_lock<mutex>&)
{
return super::data_.pull();
}
template <class T,class Container, class Cmp>
T sync_priority_queue<T,Container,Cmp>::pull(lock_guard<mutex>&)
{
return super::data_.pull();
}
template <class T,class Container, class Cmp>
T sync_priority_queue<T,Container,Cmp>::pull()
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
return pull(lk);
}
//////////////////////
template <class T,class Container, class Cmp>
void sync_priority_queue<T,Container,Cmp>::pull(unique_lock<mutex>&, T& elem)
{
elem = super::data_.pull();
}
template <class T,class Container, class Cmp>
void sync_priority_queue<T,Container,Cmp>::pull(lock_guard<mutex>&, T& elem)
{
elem = super::data_.pull();
}
template <class T,class Container, class Cmp>
void sync_priority_queue<T,Container,Cmp>::pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
pull(lk, elem);
}
//////////////////////
template <class T, class Cont,class Cmp>
queue_op_status
sync_priority_queue<T,Cont,Cmp>::pull_until(const clock::time_point& tp, T& elem)
{
unique_lock<mutex> lk(super::mtx_);
if (queue_op_status::timeout == super::wait_until_not_empty_until(lk, tp))
return queue_op_status::timeout;
pull(lk, elem);
return queue_op_status::success;
}
//////////////////////
template <class T, class Cont,class Cmp>
queue_op_status
sync_priority_queue<T,Cont,Cmp>::pull_for(const clock::duration& dura, T& elem)
{
return pull_until(clock::now() + dura, elem);
}
//////////////////////
template <class T, class Container,class Cmp>
queue_op_status
sync_priority_queue<T,Container,Cmp>::try_pull(unique_lock<mutex>& lk, T& elem)
{
if (super::empty(lk))
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::empty;
}
pull(lk, elem);
return queue_op_status::success;
}
template <class T, class Container,class Cmp>
queue_op_status
sync_priority_queue<T,Container,Cmp>::try_pull(lock_guard<mutex>& lk, T& elem)
{
if (super::empty(lk))
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::empty;
}
pull(lk, elem);
return queue_op_status::success;
}
template <class T, class Container,class Cmp>
queue_op_status
sync_priority_queue<T,Container,Cmp>::try_pull(T& elem)
{
lock_guard<mutex> lk(super::mtx_);
return try_pull(lk, elem);
}
//////////////////////
template <class T,class Container, class Cmp>
queue_op_status sync_priority_queue<T,Container,Cmp>::wait_pull(unique_lock<mutex>& lk, T& elem)
{
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(lk, elem);
return queue_op_status::success;
}
template <class T,class Container, class Cmp>
queue_op_status sync_priority_queue<T,Container,Cmp>::wait_pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
return wait_pull(lk, elem);
}
//////////////////////
template <class T,class Container, class Cmp>
queue_op_status sync_priority_queue<T,Container,Cmp>::nonblocking_pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_, try_to_lock);
if (!lk.owns_lock()) return queue_op_status::busy;
return try_pull(lk, elem);
}
} //end concurrent namespace
using concurrent::sync_priority_queue;
} //end boost namespace
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,335 @@
#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 <iostream>
#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)
{
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (super::empty(lk))
{
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (super::closed(lk)) return queue_op_status::closed;
}
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (has_been_closed) return queue_op_status::closed;
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
pull(elem, lk);
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
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
@@ -0,0 +1,468 @@
// Copyright (C) 2014 Ian Forbed
// Copyright (C) 2014 Vicente J. Botet Escriba
//
// 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)
//
#ifndef BOOST_THREAD_SYNC_TIMED_QUEUE_HPP
#define BOOST_THREAD_SYNC_TIMED_QUEUE_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/thread/concurrent_queues/sync_priority_queue.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace concurrent
{
namespace detail
{
template <class T, class Clock = chrono::steady_clock>
struct scheduled_type
{
typedef T value_type;
typedef Clock clock;
typedef typename clock::time_point time_point;
T data;
time_point time;
BOOST_THREAD_COPYABLE_AND_MOVABLE(scheduled_type)
scheduled_type(T const& pdata, time_point tp) : data(pdata), time(tp) {}
scheduled_type(BOOST_THREAD_RV_REF(T) pdata, time_point tp) : data(boost::move(pdata)), time(tp) {}
scheduled_type(scheduled_type const& other) : data(other.data), time(other.time) {}
scheduled_type& operator=(BOOST_THREAD_COPY_ASSIGN_REF(scheduled_type) other) {
data = other.data;
time = other.time;
return *this;
}
scheduled_type(BOOST_THREAD_RV_REF(scheduled_type) other) : data(boost::move(other.data)), time(other.time) {}
scheduled_type& operator=(BOOST_THREAD_RV_REF(scheduled_type) other) {
data = boost::move(other.data);
time = other.time;
return *this;
}
bool time_not_reached() const
{
return time > clock::now();
}
bool operator <(const scheduled_type<T> other) const
{
return this->time > other.time;
}
}; //end struct
} //end detail namespace
template <class T, class Clock = chrono::steady_clock>
class sync_timed_queue
: private sync_priority_queue<detail::scheduled_type<T, Clock> >
{
typedef detail::scheduled_type<T, Clock> stype;
typedef sync_priority_queue<stype> super;
public:
typedef T value_type;
typedef Clock clock;
typedef typename clock::duration duration;
typedef typename clock::time_point time_point;
typedef typename super::underlying_queue_type underlying_queue_type;
typedef typename super::size_type size_type;
typedef typename super::op_status op_status;
sync_timed_queue() : super() {};
~sync_timed_queue() {}
using super::size;
using super::empty;
using super::full;
using super::close;
using super::closed;
T pull();
void pull(T& elem);
template <class Duration>
queue_op_status pull_until(chrono::time_point<clock,Duration> const& tp, T& elem);
template <class Rep, class Period>
queue_op_status pull_for(chrono::duration<Rep,Period> const& dura, T& elem);
queue_op_status try_pull(T& elem);
queue_op_status wait_pull(T& elem);
queue_op_status nonblocking_pull(T& elem);
template <class Duration>
void push(const T& elem, chrono::time_point<clock,Duration> const& tp);
template <class Rep, class Period>
void push(const T& elem, chrono::duration<Rep,Period> const& dura);
template <class Duration>
void push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp);
template <class Rep, class Period>
void push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura);
template <class Duration>
queue_op_status try_push(const T& elem, chrono::time_point<clock,Duration> const& tp);
template <class Rep, class Period>
queue_op_status try_push(const T& elem, chrono::duration<Rep,Period> const& dura);
template <class Duration>
queue_op_status try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp);
template <class Rep, class Period>
queue_op_status try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura);
private:
T pull(unique_lock<mutex>&);
T pull(lock_guard<mutex>&);
void pull(unique_lock<mutex>&, T& elem);
void pull(lock_guard<mutex>&, T& elem);
queue_op_status try_pull(unique_lock<mutex>&, T& elem);
queue_op_status try_pull(lock_guard<mutex>&, T& elem);
queue_op_status wait_pull(unique_lock<mutex>& lk, T& elem);
bool wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>&);
T pull_when_time_reached(unique_lock<mutex>&);
template <class Duration>
queue_op_status pull_when_time_reached_until(unique_lock<mutex>&, chrono::time_point<clock,Duration> const& tp, T& elem);
bool time_not_reached(unique_lock<mutex>&);
bool time_not_reached(lock_guard<mutex>&);
bool empty_or_time_not_reached(unique_lock<mutex>&);
bool empty_or_time_not_reached(lock_guard<mutex>&);
sync_timed_queue(const sync_timed_queue&);
sync_timed_queue& operator=(const sync_timed_queue&);
sync_timed_queue(BOOST_THREAD_RV_REF(sync_timed_queue));
sync_timed_queue& operator=(BOOST_THREAD_RV_REF(sync_timed_queue));
}; //end class
template <class T, class Clock>
template <class Duration>
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::time_point<clock,Duration> const& tp)
{
super::push(stype(elem,tp));
}
template <class T, class Clock>
template <class Rep, class Period>
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::duration<Rep,Period> const& dura)
{
push(elem, clock::now() + dura);
}
template <class T, class Clock>
template <class Duration>
void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
{
super::push(stype(boost::move(elem),tp));
}
template <class T, class Clock>
template <class Rep, class Period>
void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
{
push(boost::move(elem), clock::now() + dura);
}
template <class T, class Clock>
template <class Duration>
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::time_point<clock,Duration> const& tp)
{
return super::try_push(stype(elem,tp));
}
template <class T, class Clock>
template <class Rep, class Period>
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::duration<Rep,Period> const& dura)
{
return try_push(elem,clock::now() + dura);
}
template <class T, class Clock>
template <class Duration>
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
{
return super::try_push(stype(boost::move(elem), tp));
}
template <class T, class Clock>
template <class Rep, class Period>
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
{
return try_push(boost::move(elem), clock::now() + dura);
}
///////////////////////////
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::time_not_reached(unique_lock<mutex>&)
{
return super::data_.top().time_not_reached();
}
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::time_not_reached(lock_guard<mutex>&)
{
return super::data_.top().time_not_reached();
}
///////////////////////////
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>& lk)
{
for (;;)
{
if (super::closed(lk)) return true;
while (! super::empty(lk)) {
if (! time_not_reached(lk)) return false;
time_point tp = super::data_.top().time;
super::not_empty_.wait_until(lk, tp);
if (super::closed(lk)) return true;
}
if (super::closed(lk)) return true;
super::not_empty_.wait(lk);
}
//return false;
}
///////////////////////////
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull_when_time_reached(unique_lock<mutex>& lk)
{
while (time_not_reached(lk))
{
super::throw_if_closed(lk);
time_point tp = super::data_.top().time;
super::not_empty_.wait_until(lk,tp);
super::wait_until_not_empty(lk);
}
return pull(lk);
}
template <class T, class Clock>
template <class Duration>
queue_op_status
sync_timed_queue<T, Clock>::pull_when_time_reached_until(unique_lock<mutex>& lk, chrono::time_point<clock,Duration> const& tp, T& elem)
{
chrono::time_point<clock,Duration> tpmin = (tp < super::data_.top().time) ? tp : super::data_.top().time;
while (time_not_reached(lk))
{
super::throw_if_closed(lk);
if (cv_status::timeout == super::not_empty_.wait_until(lk, tpmin)) {
if (time_not_reached(lk)) return queue_op_status::not_ready;
return queue_op_status::timeout;
}
}
pull(lk, elem);
return queue_op_status::success;
}
///////////////////////////
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(unique_lock<mutex>& lk)
{
if ( super::empty(lk) ) return true;
if ( time_not_reached(lk) ) return true;
return false;
}
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(lock_guard<mutex>& lk)
{
if ( super::empty(lk) ) return true;
if ( time_not_reached(lk) ) return true;
return false;
}
///////////////////////////
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
return boost::move(super::data_.pull().data);
#else
return super::data_.pull().data;
#endif
}
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
return boost::move(super::data_.pull().data);
#else
return super::data_.pull().data;
#endif
}
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull()
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
return pull_when_time_reached(lk);
}
///////////////////////////
template <class T, class Clock>
void sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&, T& elem)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
elem = boost::move(super::data_.pull().data);
#else
elem = super::data_.pull().data;
#endif
}
template <class T, class Clock>
void sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&, T& elem)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
elem = boost::move(super::data_.pull().data);
#else
elem = super::data_.pull().data;
#endif
}
template <class T, class Clock>
void sync_timed_queue<T, Clock>::pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
elem = pull_when_time_reached(lk);
}
//////////////////////
template <class T, class Clock>
template <class Duration>
queue_op_status
sync_timed_queue<T, Clock>::pull_until(chrono::time_point<clock,Duration> const& tp, T& elem)
{
unique_lock<mutex> lk(super::mtx_);
if (queue_op_status::timeout == super::wait_until_not_empty_until(lk, tp))
return queue_op_status::timeout;
return pull_when_time_reached_until(lk, tp, elem);
}
//////////////////////
template <class T, class Clock>
template <class Rep, class Period>
queue_op_status
sync_timed_queue<T, Clock>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
{
return pull_until(clock::now() + dura, elem);
}
///////////////////////////
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::try_pull(unique_lock<mutex>& lk, T& elem)
{
if ( super::empty(lk) )
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::empty;
}
if ( time_not_reached(lk) )
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::not_ready;
}
pull(lk, elem);
return queue_op_status::success;
}
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::try_pull(lock_guard<mutex>& lk, T& elem)
{
if ( super::empty(lk) )
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::empty;
}
if ( time_not_reached(lk) )
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::not_ready;
}
pull(lk, elem);
return queue_op_status::success;
}
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::try_pull(T& elem)
{
lock_guard<mutex> lk(super::mtx_);
return try_pull(lk, elem);
}
///////////////////////////
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex>& lk, T& elem)
{
if (super::empty(lk))
{
if (super::closed(lk)) return queue_op_status::closed;
}
bool has_been_closed = wait_until_not_empty_time_reached_or_closed(lk);
if (has_been_closed) return queue_op_status::closed;
pull(lk, elem);
return queue_op_status::success;
}
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
return wait_pull(lk, elem);
}
// ///////////////////////////
// template <class T, class Clock>
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex> &lk, T& elem)
// {
// 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(lk, elem);
// return queue_op_status::success;
// }
// template <class T>
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
// {
// unique_lock<mutex> lk(super::mtx_);
// return wait_pull(lk, elem);
// }
///////////////////////////
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::nonblocking_pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_, try_to_lock);
if (! lk.owns_lock()) return queue_op_status::busy;
return try_pull(lk, elem);
}
} //end concurrent namespace
using concurrent::sync_timed_queue;
} //end boost namespace
#include <boost/config/abi_suffix.hpp>
#endif