Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:09:31

0001 // Distributed under the Boost Software License, Version 1.0. (See
0002 // accompanying file LICENSE_1_0.txt or copy at
0003 // http://www.boost.org/LICENSE_1_0.txt)
0004 // (C) Copyright 2009-2012 Anthony Williams
0005 // (C) Copyright 2012 Vicente J. Botet Escriba
0006 
0007 // Based on the Anthony's idea of scoped_thread in CCiA
0008 
0009 #ifndef BOOST_THREAD_SCOPED_THREAD_HPP
0010 #define BOOST_THREAD_SCOPED_THREAD_HPP
0011 
0012 #include <boost/thread/detail/config.hpp>
0013 #include <boost/thread/detail/delete.hpp>
0014 #include <boost/thread/detail/move.hpp>
0015 #include <boost/thread/thread_functors.hpp>
0016 #include <boost/thread/thread_only.hpp>
0017 #include <boost/thread/detail/thread_interruption.hpp>
0018 
0019 #include <boost/config/abi_prefix.hpp>
0020 
0021 namespace boost
0022 {
0023 
0024   /**
0025    * RAI @c thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
0026    *
0027    * CallableThread: A callable void(thread&) .
0028    * The default is a join_if_joinable.
0029    *
0030    * thread std/boost::thread destructor terminates the program if the thread is not joinable.
0031    * Having a wrapper that can join the thread before destroying it seems a natural need.
0032    *
0033    * Example:
0034    *
0035    *     boost::strict_scoped_thread<> t((boost::thread(F)));
0036    *
0037    */
0038   template <class CallableThread = join_if_joinable, class Thread=::boost::thread>
0039   class strict_scoped_thread
0040   {
0041     Thread t_;
0042     struct dummy;
0043   public:
0044 
0045     BOOST_THREAD_NO_COPYABLE( strict_scoped_thread) /// non copyable
0046 
0047     /*
0048      *
0049      */
0050 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0051     template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, Thread>, void* >::type>
0052     explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
0053       t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
0054 #else
0055     template <class F>
0056     explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f,
0057         typename disable_if<is_same<typename decay<F>::type, Thread>, void* >::type=0) :
0058       t_(boost::forward<F>(f)) {}
0059     template <class F, class A1>
0060     strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
0061       t_(boost::forward<F>(f), boost::forward<A1>(a1)) {}
0062     template <class F, class A1, class A2>
0063     strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) :
0064       t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2)) {}
0065     template <class F, class A1, class A2, class A3>
0066     strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2, BOOST_THREAD_FWD_REF(A3) a3) :
0067       t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)) {}
0068 #endif
0069 
0070     /**
0071      * Constructor from the thread to own.
0072      *
0073      * @param t: the thread to own.
0074      *
0075      * Effects: move the thread to own @c t.
0076      */
0077     explicit strict_scoped_thread(BOOST_THREAD_RV_REF(Thread) t) BOOST_NOEXCEPT :
0078     t_(boost::move(t))
0079     {
0080     }
0081 
0082     /**
0083      * Destructor
0084      * Effects: Call the CallableThread functor before destroying the owned thread.
0085      * Remark: The CallableThread should not throw when joining the thread as the scoped variable is on a scope outside the thread function.
0086      */
0087     ~strict_scoped_thread()
0088     {
0089 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
0090       // exceptions from a destructor call std::terminate
0091       boost::this_thread::disable_interruption do_not_disturb;
0092 #endif
0093       CallableThread on_destructor;
0094 
0095       on_destructor(t_);
0096     }
0097 
0098   };
0099 
0100   /**
0101    * RAI @c thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
0102    *
0103    * CallableThread: A callable void(thread&) .
0104    * The default is join_if_joinable.
0105    *
0106    * thread std::thread destructor terminates the program if the thread is not joinable.
0107    * Having a wrapper that can join the thread before destroying it seems a natural need.
0108    *
0109    * Remark: @c scoped_thread is not a @c thread as @c thread is not designed to be derived from as a polymorphic type.
0110    * Anyway @c scoped_thread can be used in most of the contexts a @c thread could be used as it has the
0111    * same non-deprecated interface with the exception of the construction.
0112    *
0113    * Example:
0114    *
0115    *     boost::scoped_thread<> t((boost::thread(F)));
0116    *     t.interrupt();
0117    *
0118    */
0119   template <class CallableThread = join_if_joinable, class Thread=::boost::thread>
0120   class scoped_thread
0121   {
0122     Thread t_;
0123     struct dummy;
0124   public:
0125 
0126     typedef typename Thread::id id;
0127     typedef typename Thread::native_handle_type native_handle_type;
0128 
0129     BOOST_THREAD_MOVABLE_ONLY( scoped_thread) /// Movable only
0130 
0131     /**
0132      * Default Constructor.
0133      *
0134      * Effects: wraps a not-a-thread.
0135      */
0136     scoped_thread() BOOST_NOEXCEPT:
0137     t_()
0138     {
0139     }
0140 
0141     /**
0142      *
0143      */
0144 
0145 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0146     template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, Thread>, void* >::type>
0147     explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
0148       t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
0149 #else
0150     template <class F>
0151     explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f,
0152         typename disable_if<is_same<typename decay<F>::type, Thread>, void* >::type=0) :
0153       t_(boost::forward<F>(f)) {}
0154     template <class F, class A1>
0155     scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
0156       t_(boost::forward<F>(f), boost::forward<A1>(a1)) {}
0157     template <class F, class A1, class A2>
0158     scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) :
0159       t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2)) {}
0160     template <class F, class A1, class A2, class A3>
0161     scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2, BOOST_THREAD_FWD_REF(A3) a3) :
0162       t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)) {}
0163 
0164 #endif
0165     /**
0166      * Constructor from the thread to own.
0167      *
0168      * @param t: the thread to own.
0169      *
0170      * Effects: move the thread to own @c t.
0171      */
0172     explicit scoped_thread(BOOST_THREAD_RV_REF(Thread) t) BOOST_NOEXCEPT :
0173     t_(boost::move(t))
0174     {
0175     }
0176 
0177 //    explicit operator Thread()
0178 //    {
0179 //      return boost::move(t_);
0180 //    }
0181 
0182     /**
0183      * Move constructor.
0184      */
0185     scoped_thread(BOOST_RV_REF(scoped_thread) x) BOOST_NOEXCEPT :
0186     t_(boost::move(BOOST_THREAD_RV(x).t_))
0187     {}
0188 
0189     /**
0190      * Destructor
0191      *
0192      * Effects: Call the CallableThread functor before destroying the owned thread.
0193      */
0194     ~scoped_thread()
0195     {
0196 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
0197       // exceptions from a destructor call std::terminate
0198       boost::this_thread::disable_interruption do_not_disturb;
0199 #endif
0200       CallableThread on_destructor;
0201 
0202       on_destructor(t_);
0203     }
0204 
0205     /**
0206      * Move assignment.
0207      */
0208     scoped_thread& operator=(BOOST_RV_REF(scoped_thread) x)
0209     {
0210       CallableThread on_destructor;
0211 
0212       on_destructor(t_);
0213       t_ = boost::move(BOOST_THREAD_RV(x).t_);
0214       return *this;
0215     }
0216 
0217     /**
0218      *
0219      */
0220     void swap(scoped_thread& x) BOOST_NOEXCEPT
0221     {
0222       t_.swap(x.t_);
0223     }
0224 
0225     // forwarded thread functions
0226     inline id get_id() const BOOST_NOEXCEPT
0227     {
0228       return t_.get_id();
0229     }
0230 
0231     void detach()
0232     {
0233       t_.detach();
0234     }
0235 
0236     void join()
0237     {
0238       t_.join();
0239     }
0240 
0241 #ifdef BOOST_THREAD_USES_CHRONO
0242     template <class Rep, class Period>
0243     bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
0244     {
0245       return t_.try_join_for(rel_time);
0246     }
0247 
0248     template <class Clock, class Duration>
0249     bool try_join_until(const chrono::time_point<Clock, Duration>& abs_time)
0250     {
0251       return t_.try_join_until(abs_time);
0252     }
0253 #endif
0254 
0255     native_handle_type native_handle()BOOST_NOEXCEPT
0256     {
0257       return t_.native_handle();
0258     }
0259 
0260     bool joinable() const BOOST_NOEXCEPT
0261     {
0262       return t_.joinable();
0263     }
0264 
0265 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
0266     void interrupt()
0267     {
0268       t_.interrupt();
0269     }
0270 
0271     bool interruption_requested() const BOOST_NOEXCEPT
0272     {
0273       return t_.interruption_requested();
0274     }
0275 #endif
0276 
0277     static unsigned hardware_concurrency() BOOST_NOEXCEPT
0278     {
0279       return Thread::hardware_concurrency();
0280     }
0281 
0282 #ifdef BOOST_THREAD_PROVIDES_PHYSICAL_CONCURRENCY
0283     static unsigned physical_concurrency() BOOST_NOEXCEPT
0284     {
0285       return Thread::physical_concurrency();
0286     }
0287 #endif
0288   };
0289 
0290   /**
0291    * Effects: swaps the contents of two scoped threads.
0292    */
0293   template <class Destroyer, class Thread >
0294   void swap(scoped_thread<Destroyer, Thread>& lhs, scoped_thread<Destroyer, Thread>& rhs)
0295 BOOST_NOEXCEPT {
0296   return lhs.swap(rhs);
0297 }
0298 
0299   typedef scoped_thread<> joining_thread;
0300 }
0301 #include <boost/config/abi_suffix.hpp>
0302 
0303 #endif