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
							 |