Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:01:11

0001 // Copyright (C) 2014 Vicente J. Botet Escriba
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 //
0006 // 2013/11 Vicente J. Botet Escriba
0007 //    first implementation of a simple serial scheduler.
0008 
0009 #ifndef BOOST_THREAD_INLINE_EXECUTOR_HPP
0010 #define BOOST_THREAD_INLINE_EXECUTOR_HPP
0011 
0012 #include <boost/thread/detail/config.hpp>
0013 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
0014 
0015 #include <exception> // std::terminate
0016 #include <boost/throw_exception.hpp>
0017 #include <boost/thread/detail/delete.hpp>
0018 #include <boost/thread/detail/move.hpp>
0019 #include <boost/thread/executors/work.hpp>
0020 #include <boost/thread/mutex.hpp>
0021 #include <boost/thread/lock_guard.hpp>
0022 #include <boost/thread/concurrent_queues/queue_op_status.hpp> // sync_queue_is_closed
0023 
0024 #include <boost/config/abi_prefix.hpp>
0025 
0026 namespace boost
0027 {
0028 namespace executors
0029 {
0030   class inline_executor
0031   {
0032   public:
0033     /// type-erasure to store the works to do
0034     typedef  executors::work work;
0035     bool closed_;
0036     mutable mutex mtx_;
0037     /**
0038      * Effects: try to execute one task.
0039      * Returns: whether a task has been executed.
0040      * Throws: whatever the current task constructor throws or the task() throws.
0041      */
0042     bool try_executing_one()
0043     {
0044       return false;
0045     }
0046 
0047   public:
0048     /// inline_executor is not copyable.
0049     BOOST_THREAD_NO_COPYABLE(inline_executor)
0050 
0051     /**
0052      * \b Effects: creates a inline executor that runs closures immediately.
0053      *
0054      * \b Throws: Nothing.
0055      */
0056     inline_executor()
0057     : closed_(false)
0058     {
0059     }
0060     /**
0061      * \b Effects: Destroys the inline executor.
0062      *
0063      * \b Synchronization: The completion of all the closures happen before the completion of the \c inline_executor destructor.
0064      */
0065     ~inline_executor()
0066     {
0067       // signal to all the worker thread that there will be no more submissions.
0068       close();
0069     }
0070 
0071     /**
0072      * \b Effects: close the \c inline_executor for submissions.
0073      * The loop will work until there is no more closures to run.
0074      */
0075     void close()
0076     {
0077       lock_guard<mutex> lk(mtx_);
0078       closed_ = true;
0079     }
0080 
0081     /**
0082      * \b Returns: whether the pool is closed for submissions.
0083      */
0084     bool closed(lock_guard<mutex>& )
0085     {
0086       return closed_;
0087     }
0088     bool closed()
0089     {
0090       lock_guard<mutex> lk(mtx_);
0091       return closed(lk);
0092     }
0093 
0094     /**
0095      * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible.
0096      *
0097      * \b Effects: The specified \c closure will be scheduled for execution at some point in the future.
0098      * If invoked closure throws an exception the \c inline_executor will call \c std::terminate, as is the case with threads.
0099      *
0100      * \b Synchronization: completion of \c closure on a particular thread happens before destruction of thread's thread local variables.
0101      *
0102      * \b Throws: \c sync_queue_is_closed if the thread pool is closed.
0103      * Whatever exception that can be throw while storing the closure.
0104      */
0105 
0106 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0107     template <typename Closure>
0108     void submit(Closure & closure)
0109     {
0110       {
0111         lock_guard<mutex> lk(mtx_);
0112         if (closed(lk))  BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0113       }
0114       try
0115       {
0116         closure();
0117       }
0118       catch (...)
0119       {
0120         std::terminate();
0121         return;
0122       }
0123     }
0124 #endif
0125     void submit(void (*closure)())
0126     {
0127       {
0128         lock_guard<mutex> lk(mtx_);
0129         if (closed(lk))  BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0130       }
0131       try
0132       {
0133         closure();
0134       }
0135       catch (...)
0136       {
0137         std::terminate();
0138         return;
0139       }
0140     }
0141 
0142     template <typename Closure>
0143     void submit(BOOST_THREAD_FWD_REF(Closure) closure)
0144     {
0145       {
0146         lock_guard<mutex> lk(mtx_);
0147         if (closed(lk))  BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0148       }
0149       try
0150       {
0151         closure();
0152       }
0153       catch (...)
0154       {
0155         std::terminate();
0156         return;
0157       }
0158     }
0159 
0160     /**
0161      * \b Requires: This must be called from an scheduled task.
0162      *
0163      * \b Effects: reschedule functions until pred()
0164      */
0165     template <typename Pred>
0166     bool reschedule_until(Pred const& )
0167     {
0168       return false;
0169     }
0170 
0171   };
0172 }
0173 using executors::inline_executor;
0174 }
0175 
0176 #include <boost/config/abi_suffix.hpp>
0177 
0178 #endif
0179 #endif