214 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| // 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::move(closure));
 | |
|     }
 | |
| //    void submit(work& closure) {
 | |
| //      ex.submit(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(); }
 | |
| 
 | |
|     /**
 | |
|      * \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.
 | |
|      */
 | |
| 
 | |
|     void submit(BOOST_THREAD_RV_REF(work) closure)
 | |
|     {
 | |
|       ex->submit(boost::move(closure));
 | |
|     }
 | |
| 
 | |
| #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
 | |
|     template <typename Closure>
 | |
|     void submit(Closure & closure)
 | |
|     {
 | |
|       //work w ((closure));
 | |
|       //submit(boost::move(w));
 | |
|       submit(work(closure));
 | |
|     }
 | |
| #endif
 | |
|     void submit(void (*closure)())
 | |
|     {
 | |
|       work w ((closure));
 | |
|       submit(boost::move(w));
 | |
|       //submit(work(closure));
 | |
|     }
 | |
| 
 | |
|     template <typename Closure>
 | |
|     void submit(BOOST_THREAD_FWD_REF(Closure) closure)
 | |
|     {
 | |
|       work w((boost::forward<Closure>(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
 | 
