| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| #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 | ||
| { | ||
|
|
||
| template <typename Queue> | ||
| class queue_adaptor : public queue_base<typename Queue::value_type> | ||
| { | ||
| Queue queue; | ||
| public: | ||
| typedef typename Queue::value_type value_type; | ||
| typedef std::size_t size_type; | ||
|
|
||
| // Constructors/Assignment/Destructors | ||
|
|
||
| queue_adaptor() {} | ||
|
|
||
| // 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 push_back(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(boost::forward<value_type>(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_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(boost::forward<value_type>(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_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(boost::forward<value_type>(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_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(boost::forward<value_type>(x)); } | ||
| queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); } | ||
|
|
||
| }; | ||
|
|
||
| } | ||
| using concurrent::queue_adaptor; | ||
|
|
||
| } | ||
|
|
||
| #include <boost/config/abi_suffix.hpp> | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| #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/config/abi_prefix.hpp> | ||
|
|
||
| namespace boost | ||
| { | ||
| namespace concurrent | ||
| { | ||
|
|
||
| template <typename ValueType> | ||
| class queue_base | ||
| { | ||
| public: | ||
| typedef ValueType value_type; | ||
| typedef std::size_t size_type; | ||
|
|
||
| // Constructors/Assignment/Destructors | ||
| virtual ~queue_base() {}; | ||
|
|
||
| // 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 push_back(BOOST_THREAD_RV_REF(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_push_back(BOOST_THREAD_RV_REF(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_push_back(BOOST_THREAD_RV_REF(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_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0; | ||
| virtual queue_op_status wait_pull_front(ValueType& elem) = 0; | ||
|
|
||
| }; | ||
|
|
||
|
|
||
| } | ||
| using concurrent::queue_base; | ||
|
|
||
| } | ||
|
|
||
| #include <boost/config/abi_suffix.hpp> | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| #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 } | ||
| BOOST_SCOPED_ENUM_DECLARE_END(queue_op_status) | ||
| } | ||
|
|
||
| #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; | ||
|
|
||
| } | ||
|
|
||
| #include <boost/config/abi_suffix.hpp> | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| #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_back(x); } | ||
| void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(forward<value_type>(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_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(forward<value_type>(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_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(forward<value_type>(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_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(forward<value_type>(x)); } | ||
| queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_back(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 push(const value_type& x) { queue.push_front(x); } | ||
| void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push_front(forward<value_type>(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_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_front(forward<value_type>(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_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_front(forward<value_type>(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_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_front(forward<value_type>(x)); } | ||
| queue_op_status wait_pull(value_type& x) { return queue.wait_pull_front(x); } | ||
|
|
||
| }; | ||
|
|
||
| #if 0 | ||
| 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 { | ||
| typedef queue_back_view<queue_base<T> > type; | ||
| }; | ||
| template <class T> | ||
| struct queue_front { | ||
| typedef queue_front_view<queue_base<T> > type; | ||
| }; | ||
|
|
||
| #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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,209 @@ | ||
| // 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_EXECUTORS_GENERIC_EXECUTOR_REF_HPP | ||
| #define BOOST_THREAD_EXECUTORS_GENERIC_EXECUTOR_REF_HPP | ||
|
|
||
| #include <boost/thread/detail/config.hpp> | ||
|
|
||
| #include <boost/thread/detail/delete.hpp> | ||
| #include <boost/thread/detail/move.hpp> | ||
| #include <boost/thread/executors/executor.hpp> | ||
|
|
||
| #include <boost/shared_ptr.hpp> | ||
|
|
||
| #include <boost/config/abi_prefix.hpp> | ||
|
|
||
| namespace boost | ||
| { | ||
| namespace executors | ||
| { | ||
|
|
||
| template <class Executor> | ||
| class executor_ref : public executor | ||
| { | ||
| Executor& ex; | ||
| public: | ||
| /// type-erasure to store the works to do | ||
| typedef executors::work work; | ||
|
|
||
| /// executor is not copyable. | ||
| BOOST_THREAD_NO_COPYABLE(executor_ref) | ||
| executor_ref(Executor& ex) : ex(ex) {} | ||
|
|
||
| /** | ||
| * \par Effects | ||
| * Destroys the executor. | ||
| * | ||
| * \par Synchronization | ||
| * The completion of all the closures happen before the completion of the executor destructor. | ||
| */ | ||
| ~executor_ref() {}; | ||
|
|
||
| /** | ||
| * \par Effects | ||
| * Close the \c executor for submissions. | ||
| * The worker threads will work until there is no more closures to run. | ||
| */ | ||
| void close() { ex.close(); } | ||
|
|
||
| /** | ||
| * \par Returns | ||
| * Whether the pool is closed for submissions. | ||
| */ | ||
| bool closed() { return ex.closed(); } | ||
|
|
||
| /** | ||
| * \par Effects | ||
| * The specified closure will be scheduled for execution at some point in the future. | ||
| * If invoked closure throws an exception the executor will call std::terminate, as is the case with threads. | ||
| * | ||
| * \par Synchronization | ||
| * Ccompletion of closure on a particular thread happens before destruction of thread's thread local variables. | ||
| * | ||
| * \par Throws | ||
| * \c sync_queue_is_closed if the thread pool is closed. | ||
| * Whatever exception that can be throw while storing the closure. | ||
| */ | ||
| void submit(BOOST_THREAD_RV_REF(work) closure) { | ||
| //ex.submit(boost::forward<work>(closure)); // todo check why this doesn't work | ||
| ex.submit(boost::move(closure)); | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * \par Effects | ||
| * Try to execute one task. | ||
| * | ||
| * \par Returns | ||
| * Whether a task has been executed. | ||
| * | ||
| * \par Throws | ||
| * Whatever the current task constructor throws or the task() throws. | ||
| */ | ||
| bool try_executing_one() { return ex.try_executing_one(); } | ||
|
|
||
| }; | ||
|
|
||
| class generic_executor_ref | ||
| { | ||
| shared_ptr<executor> ex; | ||
| public: | ||
| /// type-erasure to store the works to do | ||
| typedef executors::work work; | ||
|
|
||
| template<typename Executor> | ||
| generic_executor_ref(Executor& ex) | ||
| //: ex(make_shared<executor_ref<Executor> >(ex)) // todo check why this doesn't works with C++03 | ||
| : ex( new executor_ref<Executor>(ex) ) | ||
| { | ||
| } | ||
|
|
||
| //generic_executor_ref(generic_executor_ref const& other) noexcept {} | ||
| //generic_executor_ref& operator=(generic_executor_ref const& other) noexcept {} | ||
|
|
||
|
|
||
| /** | ||
| * \par Effects | ||
| * Close the \c executor for submissions. | ||
| * The worker threads will work until there is no more closures to run. | ||
| */ | ||
| void close() { ex->close(); } | ||
|
|
||
| /** | ||
| * \par Returns | ||
| * Whether the pool is closed for submissions. | ||
| */ | ||
| bool closed() { return ex->closed(); } | ||
|
|
||
| void submit(BOOST_THREAD_RV_REF(work) closure) | ||
| { | ||
| ex->submit(boost::forward<work>(closure)); | ||
| } | ||
|
|
||
| /** | ||
| * \par Requires | ||
| * \c Closure is a model of Callable(void()) and a model of CopyConstructible/MoveConstructible. | ||
| * | ||
| * \par Effects | ||
| * The specified closure will be scheduled for execution at some point in the future. | ||
| * If invoked closure throws an exception the thread pool will call std::terminate, as is the case with threads. | ||
| * | ||
| * \par Synchronization | ||
| * Completion of closure on a particular thread happens before destruction of thread's thread local variables. | ||
| * | ||
| * \par Throws | ||
| * \c sync_queue_is_closed if the thread pool is closed. | ||
| * Whatever exception that can be throw while storing the closure. | ||
| */ | ||
|
|
||
| #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | ||
| template <typename Closure> | ||
| void submit(Closure & closure) | ||
| { | ||
| work w ((closure)); | ||
| submit(boost::move(w)); | ||
| } | ||
| #endif | ||
| void submit(void (*closure)()) | ||
| { | ||
| work w ((closure)); | ||
| submit(boost::move(w)); | ||
| } | ||
|
|
||
| template <typename Closure> | ||
| void submit(BOOST_THREAD_RV_REF(Closure) closure) | ||
| { | ||
| work w = boost::move(closure); | ||
| submit(boost::move(w)); | ||
| } | ||
|
|
||
| // size_t num_pending_closures() const | ||
| // { | ||
| // return ex->num_pending_closures(); | ||
| // } | ||
|
|
||
| /** | ||
| * \par Effects | ||
| * Try to execute one task. | ||
| * | ||
| * \par Returns | ||
| * Whether a task has been executed. | ||
| * | ||
| * \par Throws | ||
| * Whatever the current task constructor throws or the task() throws. | ||
| */ | ||
| bool try_executing_one() { return ex->try_executing_one(); } | ||
|
|
||
| /** | ||
| * \par Requires | ||
| * This must be called from an scheduled task. | ||
| * | ||
| * \par Effects | ||
| * reschedule functions until pred() | ||
| */ | ||
| template <typename Pred> | ||
| bool reschedule_until(Pred const& pred) | ||
| { | ||
| do { | ||
| //schedule_one_or_yield(); | ||
| if ( ! try_executing_one()) | ||
| { | ||
| return false; | ||
| } | ||
| } while (! pred()); | ||
| return true; | ||
| } | ||
|
|
||
| }; | ||
| } | ||
| using executors::executor_ref; | ||
| using executors::generic_executor_ref; | ||
| } | ||
|
|
||
| #include <boost/config/abi_suffix.hpp> | ||
|
|
||
| #endif |