LCOV - code coverage report
Current view: top level - usr/include/boost/thread/detail - thread.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 3 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #ifndef BOOST_THREAD_THREAD_COMMON_HPP
       2             : #define BOOST_THREAD_THREAD_COMMON_HPP
       3             : // Distributed under the Boost Software License, Version 1.0. (See
       4             : // accompanying file LICENSE_1_0.txt or copy at
       5             : // http://www.boost.org/LICENSE_1_0.txt)
       6             : // (C) Copyright 2007-2010 Anthony Williams
       7             : // (C) Copyright 2011-2012 Vicente J. Botet Escriba
       8             : 
       9             : #include <boost/thread/detail/config.hpp>
      10             : #include <boost/predef/platform.h>
      11             : 
      12             : #include <boost/thread/exceptions.hpp>
      13             : #ifndef BOOST_NO_IOSTREAM
      14             : #include <ostream>
      15             : #endif
      16             : #include <boost/thread/detail/move.hpp>
      17             : #include <boost/thread/mutex.hpp>
      18             : #if defined BOOST_THREAD_USES_DATETIME
      19             : #include <boost/thread/xtime.hpp>
      20             : #endif
      21             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
      22             : #include <boost/thread/interruption.hpp>
      23             : #endif
      24             : #include <boost/thread/detail/thread_heap_alloc.hpp>
      25             : #include <boost/thread/detail/make_tuple_indices.hpp>
      26             : #include <boost/thread/detail/invoke.hpp>
      27             : #include <boost/thread/detail/is_convertible.hpp>
      28             : #include <boost/assert.hpp>
      29             : #include <list>
      30             : #include <algorithm>
      31             : #include <boost/core/ref.hpp>
      32             : #include <boost/cstdint.hpp>
      33             : #include <boost/bind.hpp>
      34             : #include <stdlib.h>
      35             : #include <memory>
      36             : #include <boost/core/enable_if.hpp>
      37             : #include <boost/type_traits/remove_reference.hpp>
      38             : #include <boost/io/ios_state.hpp>
      39             : #include <boost/type_traits/is_same.hpp>
      40             : #include <boost/type_traits/decay.hpp>
      41             : #include <boost/functional/hash.hpp>
      42             : #include <boost/thread/detail/platform_time.hpp>
      43             : #ifdef BOOST_THREAD_USES_CHRONO
      44             : #include <boost/chrono/system_clocks.hpp>
      45             : #include <boost/chrono/ceil.hpp>
      46             : #endif
      47             : 
      48             : #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
      49             : #include <tuple>
      50             : #endif
      51             : #include <boost/config/abi_prefix.hpp>
      52             : 
      53             : #ifdef BOOST_MSVC
      54             : #pragma warning(push)
      55             : #pragma warning(disable:4251)
      56             : #endif
      57             : 
      58             : namespace boost
      59             : {
      60             : 
      61             :     namespace detail
      62             :     {
      63             : 
      64             : #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
      65             : 
      66             :       template<typename F, class ...ArgTypes>
      67             :       class thread_data:
      68             :           public detail::thread_data_base
      69             :       {
      70             :       public:
      71             :           BOOST_THREAD_NO_COPYABLE(thread_data)
      72             :             thread_data(BOOST_THREAD_RV_REF(F) f_, BOOST_THREAD_RV_REF(ArgTypes)... args_):
      73             :               fp(boost::forward<F>(f_), boost::forward<ArgTypes>(args_)...)
      74             :             {}
      75             :           template <std::size_t ...Indices>
      76             :           void run2(tuple_indices<Indices...>)
      77             :           {
      78             : 
      79             :               detail::invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
      80             :           }
      81             :           void run()
      82             :           {
      83             :               typedef typename make_tuple_indices<std::tuple_size<std::tuple<F, ArgTypes...> >::value, 1>::type index_type;
      84             : 
      85             :               run2(index_type());
      86             :           }
      87             : 
      88             :       private:
      89             :           std::tuple<typename decay<F>::type, typename decay<ArgTypes>::type...> fp;
      90             :       };
      91             : #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
      92             : 
      93             :         template<typename F>
      94             :         class thread_data:
      95             :             public detail::thread_data_base
      96             :         {
      97             :         public:
      98             :             BOOST_THREAD_NO_COPYABLE(thread_data)
      99             : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
     100             :               thread_data(BOOST_THREAD_RV_REF(F) f_):
     101             :                 f(boost::forward<F>(f_))
     102             :               {}
     103             : // This overloading must be removed if we want the packaged_task's tests to pass.
     104             : //            thread_data(F& f_):
     105             : //                f(f_)
     106             : //            {}
     107             : #else
     108             : 
     109             :             thread_data(BOOST_THREAD_RV_REF(F) f_):
     110             :               f(f_)
     111             :             {}
     112             :             thread_data(F f_):
     113             :                 f(f_)
     114             :             {}
     115             : #endif
     116             :             //thread_data() {}
     117             : 
     118           0 :             void run()
     119             :             {
     120           0 :                 f();
     121           0 :             }
     122             : 
     123             :         private:
     124             :             F f;
     125             :         };
     126             : 
     127             :         template<typename F>
     128             :         class thread_data<boost::reference_wrapper<F> >:
     129             :             public detail::thread_data_base
     130             :         {
     131             :         private:
     132             :             F& f;
     133             :         public:
     134             :             BOOST_THREAD_NO_COPYABLE(thread_data)
     135             :             thread_data(boost::reference_wrapper<F> f_):
     136             :                 f(f_)
     137             :             {}
     138             :             void run()
     139             :             {
     140             :                 f();
     141             :             }
     142             :         };
     143             : 
     144             :         template<typename F>
     145             :         class thread_data<const boost::reference_wrapper<F> >:
     146             :             public detail::thread_data_base
     147             :         {
     148             :         private:
     149             :             F& f;
     150             :         public:
     151             :             BOOST_THREAD_NO_COPYABLE(thread_data)
     152             :             thread_data(const boost::reference_wrapper<F> f_):
     153             :                 f(f_)
     154             :             {}
     155             :             void run()
     156             :             {
     157             :                 f();
     158             :             }
     159             :         };
     160             : #endif
     161             :     }
     162             : 
     163             :     class BOOST_THREAD_DECL thread
     164             :     {
     165             :     public:
     166             :       typedef thread_attributes attributes;
     167             : 
     168             :       BOOST_THREAD_MOVABLE_ONLY(thread)
     169             :     private:
     170             : 
     171             :         struct dummy;
     172             : 
     173             :         void release_handle();
     174             : 
     175             :         detail::thread_data_ptr thread_info;
     176             : 
     177             :     private:
     178             :         bool start_thread_noexcept();
     179             :         bool start_thread_noexcept(const attributes& attr);
     180             :         void start_thread()
     181             :         {
     182             :           if (!start_thread_noexcept())
     183             :           {
     184             :             boost::throw_exception(thread_resource_error());
     185             :           }
     186             :         }
     187             :         void start_thread(const attributes& attr)
     188             :         {
     189             :           if (!start_thread_noexcept(attr))
     190             :           {
     191             :             boost::throw_exception(thread_resource_error());
     192             :           }
     193             :         }
     194             : 
     195             :         explicit thread(detail::thread_data_ptr data);
     196             : 
     197             :         detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const;
     198             : 
     199             : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
     200             : #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
     201             :         template<typename F, class ...ArgTypes>
     202             :         static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
     203             :         {
     204             :             return detail::thread_data_ptr(detail::heap_new<
     205             :                   detail::thread_data<typename boost::remove_reference<F>::type, ArgTypes...>
     206             :                   >(
     207             :                     boost::forward<F>(f), boost::forward<ArgTypes>(args)...
     208             :                   )
     209             :                 );
     210             :         }
     211             : #else
     212             :         template<typename F>
     213             :         static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
     214             :         {
     215             :             return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >(
     216             :                 boost::forward<F>(f)));
     217             :         }
     218             : #endif
     219             :         static inline detail::thread_data_ptr make_thread_info(void (*f)())
     220             :         {
     221             :             return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(
     222             :                 boost::forward<void(*)()>(f)));
     223             :         }
     224             : #else
     225             :         template<typename F>
     226             :         static inline detail::thread_data_ptr make_thread_info(F f
     227             :             , typename disable_if_c<
     228             :                 //boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value ||
     229             :                 is_same<typename decay<F>::type, thread>::value,
     230             :                 dummy* >::type=0
     231             :                 )
     232             :         {
     233             :             return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
     234             :         }
     235             :         template<typename F>
     236             :         static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
     237             :         {
     238             :             return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
     239             :         }
     240             : 
     241             : #endif
     242             :     public:
     243             : #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
     244             : #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
     245             :         thread(const volatile thread&);
     246             : #endif
     247             : #endif
     248             :         thread() BOOST_NOEXCEPT;
     249             :         ~thread()
     250             :         {
     251             : 
     252             :     #if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
     253             :           if (joinable()) {
     254             :             std::terminate();
     255             :           }
     256             :     #else
     257             :             detach();
     258             :     #endif
     259             :         }
     260             : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
     261             :         template <
     262             :           class F
     263             :         >
     264             :         explicit thread(BOOST_THREAD_RV_REF(F) f
     265             :         //, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
     266             :         ):
     267             :           thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
     268             :         {
     269             :             start_thread();
     270             :         }
     271             :         template <
     272             :           class F
     273             :         >
     274             :         thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f):
     275             :           thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
     276             :         {
     277             :             start_thread(attrs);
     278             :         }
     279             : 
     280             : #else
     281             : #ifdef BOOST_NO_SFINAE
     282             :         template <class F>
     283             :         explicit thread(F f):
     284             :             thread_info(make_thread_info(f))
     285             :         {
     286             :             start_thread();
     287             :         }
     288             :         template <class F>
     289             :         thread(attributes const& attrs, F f):
     290             :             thread_info(make_thread_info(f))
     291             :         {
     292             :             start_thread(attrs);
     293             :         }
     294             : #else
     295             :         template <class F>
     296             :         explicit thread(F f
     297             :         , typename disable_if_c<
     298             :         boost::thread_detail::is_rv<F>::value // todo as a thread_detail::is_rv
     299             :         //boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value
     300             :             //|| is_same<typename decay<F>::type, thread>::value
     301             :            , dummy* >::type=0
     302             :         ):
     303             :             thread_info(make_thread_info(f))
     304             :         {
     305             :             start_thread();
     306             :         }
     307             :         template <class F>
     308             :         thread(attributes const& attrs, F f
     309             :             , typename disable_if<boost::thread_detail::is_rv<F>, dummy* >::type=0
     310             :             //, typename disable_if<boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0
     311             :         ):
     312             :             thread_info(make_thread_info(f))
     313             :         {
     314             :             start_thread(attrs);
     315             :         }
     316             : #endif
     317             :         template <class F>
     318             :         explicit thread(BOOST_THREAD_RV_REF(F) f
     319             :         , typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
     320             :         ):
     321             : #ifdef BOOST_THREAD_USES_MOVE
     322             :         thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
     323             : #else
     324             :         thread_info(make_thread_info(f)) // todo : Add forward
     325             : #endif
     326             :         {
     327             :             start_thread();
     328             :         }
     329             : 
     330             :         template <class F>
     331             :         thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f):
     332             : #ifdef BOOST_THREAD_USES_MOVE
     333             :             thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
     334             : #else
     335             :             thread_info(make_thread_info(f)) // todo : Add forward
     336             : #endif
     337             :         {
     338             :             start_thread(attrs);
     339             :         }
     340             : #endif
     341             :         thread(BOOST_THREAD_RV_REF(thread) x) BOOST_NOEXCEPT
     342             :         {
     343             :             thread_info=BOOST_THREAD_RV(x).thread_info;
     344             :             BOOST_THREAD_RV(x).thread_info.reset();
     345             :         }
     346             : #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
     347             : #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
     348             :         thread& operator=(thread x)
     349             :         {
     350             :             swap(x);
     351             :             return *this;
     352             :         }
     353             : #endif
     354             : #endif
     355             : 
     356             :         thread& operator=(BOOST_THREAD_RV_REF(thread) other) BOOST_NOEXCEPT
     357             :         {
     358             : 
     359             : #if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
     360             :             if (joinable()) std::terminate();
     361             : #else
     362             :             detach();
     363             : #endif
     364             :             thread_info=BOOST_THREAD_RV(other).thread_info;
     365             :             BOOST_THREAD_RV(other).thread_info.reset();
     366             :             return *this;
     367             :         }
     368             : 
     369             : #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
     370             :         template <class F, class Arg, class ...Args>
     371             :         thread(F&& f, Arg&& arg, Args&&... args) :
     372             :           thread_info(make_thread_info(
     373             :               thread_detail::decay_copy(boost::forward<F>(f)),
     374             :               thread_detail::decay_copy(boost::forward<Arg>(arg)),
     375             :               thread_detail::decay_copy(boost::forward<Args>(args))...)
     376             :           )
     377             : 
     378             :         {
     379             :           start_thread();
     380             :         }
     381             :         template <class F, class Arg, class ...Args>
     382             :         thread(attributes const& attrs, F&& f, Arg&& arg, Args&&... args) :
     383             :           thread_info(make_thread_info(
     384             :               thread_detail::decay_copy(boost::forward<F>(f)),
     385             :               thread_detail::decay_copy(boost::forward<Arg>(arg)),
     386             :               thread_detail::decay_copy(boost::forward<Args>(args))...)
     387             :           )
     388             : 
     389             :         {
     390             :           start_thread(attrs);
     391             :         }
     392             : #else
     393             :         template <class F,class A1>
     394             :         thread(F f,A1 a1,typename disable_if<boost::thread_detail::is_convertible<F&,thread_attributes >, dummy* >::type=0):
     395             :             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1)))
     396             :         {
     397             :             start_thread();
     398             :         }
     399             :         template <class F,class A1,class A2>
     400             :         thread(F f,A1 a1,A2 a2):
     401             :             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2)))
     402             :         {
     403             :             start_thread();
     404             :         }
     405             : 
     406             :         template <class F,class A1,class A2,class A3>
     407             :         thread(F f,A1 a1,A2 a2,A3 a3):
     408             :             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3)))
     409             :         {
     410             :             start_thread();
     411             :         }
     412             : 
     413             :         template <class F,class A1,class A2,class A3,class A4>
     414             :         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4):
     415             :             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4)))
     416             :         {
     417             :             start_thread();
     418             :         }
     419             : 
     420             :         template <class F,class A1,class A2,class A3,class A4,class A5>
     421             :         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5):
     422             :             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5)))
     423             :         {
     424             :             start_thread();
     425             :         }
     426             : 
     427             :         template <class F,class A1,class A2,class A3,class A4,class A5,class A6>
     428             :         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6):
     429             :             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6)))
     430             :         {
     431             :             start_thread();
     432             :         }
     433             : 
     434             :         template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7>
     435             :         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7):
     436             :             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7)))
     437             :         {
     438             :             start_thread();
     439             :         }
     440             : 
     441             :         template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8>
     442             :         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8):
     443             :             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8)))
     444             :         {
     445             :             start_thread();
     446             :         }
     447             : 
     448             :         template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8,class A9>
     449             :         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9):
     450             :             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8,a9)))
     451             :         {
     452             :             start_thread();
     453             :         }
     454             : #endif
     455             :         void swap(thread& x) BOOST_NOEXCEPT
     456             :         {
     457             :             thread_info.swap(x.thread_info);
     458             :         }
     459             : 
     460             :         class id;
     461             :         id get_id() const BOOST_NOEXCEPT;
     462             : 
     463             :         bool joinable() const BOOST_NOEXCEPT;
     464             :     private:
     465             :         bool join_noexcept();
     466             :         bool do_try_join_until_noexcept(detail::internal_platform_timepoint const &timeout, bool& res);
     467             :         bool do_try_join_until(detail::internal_platform_timepoint const &timeout);
     468             :     public:
     469             :         void join();
     470             : 
     471             : #ifdef BOOST_THREAD_USES_CHRONO
     472             :         template <class Duration>
     473             :         bool try_join_until(const chrono::time_point<detail::internal_chrono_clock, Duration>& t)
     474             :         {
     475             :           return do_try_join_until(boost::detail::internal_platform_timepoint(t));
     476             :         }
     477             : 
     478             :         template <class Clock, class Duration>
     479             :         bool try_join_until(const chrono::time_point<Clock, Duration>& t)
     480             :         {
     481             :           typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
     482             :           common_duration d(t - Clock::now());
     483             :           d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
     484             :           while ( ! try_join_until(detail::internal_chrono_clock::now() + d) )
     485             :           {
     486             :             d = t - Clock::now();
     487             :             if ( d <= common_duration::zero() ) return false; // timeout occurred
     488             :             d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
     489             :           }
     490             :           return true;
     491             :         }
     492             : 
     493             :         template <class Rep, class Period>
     494             :         bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
     495             :         {
     496             :           return try_join_until(chrono::steady_clock::now() + rel_time);
     497             :         }
     498             : #endif
     499             : #if defined BOOST_THREAD_USES_DATETIME
     500             :         bool timed_join(const system_time& abs_time)
     501             :         {
     502             :           const detail::real_platform_timepoint ts(abs_time);
     503             : #if defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
     504             :           detail::platform_duration d(ts - detail::real_platform_clock::now());
     505             :           d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
     506             :           while ( ! do_try_join_until(detail::internal_platform_clock::now() + d) )
     507             :           {
     508             :             d = ts - detail::real_platform_clock::now();
     509             :             if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
     510             :             d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
     511             :           }
     512             :           return true;
     513             : #else
     514             :           return do_try_join_until(ts);
     515             : #endif
     516             :         }
     517             : 
     518             :         template<typename TimeDuration>
     519             :         bool timed_join(TimeDuration const& rel_time)
     520             :         {
     521             :           detail::platform_duration d(rel_time);
     522             : #if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
     523             :           const detail::mono_platform_timepoint ts(detail::mono_platform_clock::now() + d);
     524             :           d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
     525             :           while ( ! do_try_join_until(detail::internal_platform_clock::now() + d) )
     526             :           {
     527             :             d = ts - detail::mono_platform_clock::now();
     528             :             if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
     529             :             d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
     530             :           }
     531             :           return true;
     532             : #else
     533             :           return do_try_join_until(detail::internal_platform_clock::now() + d);
     534             : #endif
     535             :         }
     536             : #endif
     537             :         void detach();
     538             : 
     539             :         static unsigned hardware_concurrency() BOOST_NOEXCEPT;
     540             :         static unsigned physical_concurrency() BOOST_NOEXCEPT;
     541             : 
     542             : #define BOOST_THREAD_DEFINES_THREAD_NATIVE_HANDLE
     543             :         typedef detail::thread_data_base::native_handle_type native_handle_type;
     544             :         native_handle_type native_handle();
     545             : 
     546             : #if defined BOOST_THREAD_PROVIDES_THREAD_EQ
     547             :         // Use thread::id when comparisions are needed
     548             :         // backwards compatibility
     549             :         bool operator==(const thread& other) const;
     550             :         bool operator!=(const thread& other) const;
     551             : #endif
     552             : #if defined BOOST_THREAD_USES_DATETIME
     553             :         static inline void yield() BOOST_NOEXCEPT
     554             :         {
     555             :             this_thread::yield();
     556             :         }
     557             : 
     558             :         static inline void sleep(const system_time& xt)
     559             :         {
     560             :             this_thread::sleep(xt);
     561             :         }
     562             : #endif
     563             : 
     564             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     565             :         // extensions
     566             :         void interrupt();
     567             :         bool interruption_requested() const BOOST_NOEXCEPT;
     568             : #endif
     569             :     };
     570             : 
     571             :     inline void swap(thread& lhs,thread& rhs) BOOST_NOEXCEPT
     572             :     {
     573             :         return lhs.swap(rhs);
     574             :     }
     575             : 
     576             : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
     577             :     inline thread&& move(thread& t) BOOST_NOEXCEPT
     578             :     {
     579             :         return static_cast<thread&&>(t);
     580             :     }
     581             : #endif
     582             : 
     583             :     BOOST_THREAD_DCL_MOVABLE(thread)
     584             : 
     585             :     namespace this_thread
     586             :     {
     587             : #ifdef BOOST_THREAD_PLATFORM_PTHREAD
     588             :         thread::id get_id() BOOST_NOEXCEPT;
     589             : #else
     590             :         thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT;
     591             : #endif
     592             : 
     593             : #if defined BOOST_THREAD_USES_DATETIME
     594             :         inline BOOST_SYMBOL_VISIBLE void sleep(::boost::xtime const& abs_time)
     595             :         {
     596             :             sleep(system_time(abs_time));
     597             :         }
     598             : #endif
     599             :     }
     600             : 
     601             :     class BOOST_SYMBOL_VISIBLE thread::id
     602             :     {
     603             :     private:
     604             :         friend inline
     605             :         std::size_t
     606             :         hash_value(const thread::id &v)
     607             :         {
     608             : #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
     609             :           return hash_value(v.thread_data);
     610             : #else
     611             :           return hash_value(v.thread_data.get());
     612             : #endif
     613             :         }
     614             : 
     615             : #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
     616             : #if defined(BOOST_THREAD_PLATFORM_WIN32)
     617             :         typedef unsigned int data;
     618             : #else
     619             :         typedef thread::native_handle_type data;
     620             : #endif
     621             : #else
     622             :         typedef detail::thread_data_ptr data;
     623             : #endif
     624             :         data thread_data;
     625             : 
     626             :         id(data thread_data_):
     627             :             thread_data(thread_data_)
     628             :         {}
     629             :         friend class thread;
     630             :         friend id BOOST_THREAD_DECL this_thread::get_id() BOOST_NOEXCEPT;
     631             :     public:
     632             :         id() BOOST_NOEXCEPT:
     633             : #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
     634             :         thread_data(0)
     635             : #else
     636             :         thread_data()
     637             : #endif
     638             :         {}
     639             : 
     640             :         id(const id& other) BOOST_NOEXCEPT :
     641             :             thread_data(other.thread_data)
     642             :         {}
     643             : 
     644             :         bool operator==(const id& y) const BOOST_NOEXCEPT
     645             :         {
     646             :             return thread_data==y.thread_data;
     647             :         }
     648             : 
     649             :         bool operator!=(const id& y) const BOOST_NOEXCEPT
     650             :         {
     651             :             return thread_data!=y.thread_data;
     652             :         }
     653             : 
     654             :         bool operator<(const id& y) const BOOST_NOEXCEPT
     655             :         {
     656             :             return thread_data<y.thread_data;
     657             :         }
     658             : 
     659             :         bool operator>(const id& y) const BOOST_NOEXCEPT
     660             :         {
     661             :             return y.thread_data<thread_data;
     662             :         }
     663             : 
     664             :         bool operator<=(const id& y) const BOOST_NOEXCEPT
     665             :         {
     666             :             return !(y.thread_data<thread_data);
     667             :         }
     668             : 
     669             :         bool operator>=(const id& y) const BOOST_NOEXCEPT
     670             :         {
     671             :             return !(thread_data<y.thread_data);
     672             :         }
     673             : 
     674             : #ifndef BOOST_NO_IOSTREAM
     675             : #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
     676             :         template<class charT, class traits>
     677             :         friend BOOST_SYMBOL_VISIBLE
     678             :   std::basic_ostream<charT, traits>&
     679             :         operator<<(std::basic_ostream<charT, traits>& os, const id& x)
     680             :         {
     681             :             if(x.thread_data)
     682             :             {
     683             :                 io::ios_flags_saver  ifs( os );
     684             :                 return os<< std::hex << x.thread_data;
     685             :             }
     686             :             else
     687             :             {
     688             :                 return os<<"{Not-any-thread}";
     689             :             }
     690             :         }
     691             : #else
     692             :         template<class charT, class traits>
     693             :         BOOST_SYMBOL_VISIBLE
     694             :   std::basic_ostream<charT, traits>&
     695             :         print(std::basic_ostream<charT, traits>& os) const
     696             :         {
     697             :             if(thread_data)
     698             :             {
     699             :               io::ios_flags_saver  ifs( os );
     700             :               return os<< std::hex << thread_data;
     701             :             }
     702             :             else
     703             :             {
     704             :                 return os<<"{Not-any-thread}";
     705             :             }
     706             :         }
     707             : 
     708             : #endif
     709             : #endif
     710             :     };
     711             : 
     712             : #ifdef BOOST_THREAD_PLATFORM_PTHREAD
     713             :     inline thread::id thread::get_id() const BOOST_NOEXCEPT
     714             :     {
     715             :     #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
     716             :         return const_cast<thread*>(this)->native_handle();
     717             :     #else
     718             :         detail::thread_data_ptr const local_thread_info=(get_thread_info)();
     719             :         return (local_thread_info? id(local_thread_info) : id());
     720             :     #endif
     721             :     }
     722             : 
     723             :     namespace this_thread
     724             :     {
     725             :         inline thread::id get_id() BOOST_NOEXCEPT
     726             :         {
     727             :         #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
     728             :              return pthread_self();
     729             :         #else
     730             :             boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data();
     731             :             return (thread_info?thread::id(thread_info->shared_from_this()):thread::id());
     732             :         #endif
     733             :         }
     734             :     }
     735             : #endif
     736             :     inline void thread::join() {
     737             :         if (this_thread::get_id() == get_id())
     738             :           boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));
     739             : 
     740             :         BOOST_THREAD_VERIFY_PRECONDITION( join_noexcept(),
     741             :             thread_resource_error(static_cast<int>(system::errc::invalid_argument), "boost thread: thread not joinable")
     742             :         );
     743             :     }
     744             : 
     745             :     inline bool thread::do_try_join_until(detail::internal_platform_timepoint const &timeout)
     746             :     {
     747             :         if (this_thread::get_id() == get_id())
     748             :           boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));
     749             :         bool res;
     750             :         if (do_try_join_until_noexcept(timeout, res))
     751             :         {
     752             :           return res;
     753             :         }
     754             :         else
     755             :         {
     756             :           BOOST_THREAD_THROW_ELSE_RETURN(
     757             :             (thread_resource_error(static_cast<int>(system::errc::invalid_argument), "boost thread: thread not joinable")),
     758             :             false
     759             :           );
     760             :         }
     761             :     }
     762             : 
     763             : #if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
     764             :     template<class charT, class traits>
     765             :     BOOST_SYMBOL_VISIBLE
     766             :     std::basic_ostream<charT, traits>&
     767             :     operator<<(std::basic_ostream<charT, traits>& os, const thread::id& x)
     768             :     {
     769             :         return x.print(os);
     770             :     }
     771             : #endif
     772             : 
     773             : #if defined BOOST_THREAD_PROVIDES_THREAD_EQ
     774             :     inline bool thread::operator==(const thread& other) const
     775             :     {
     776             :         return get_id()==other.get_id();
     777             :     }
     778             : 
     779             :     inline bool thread::operator!=(const thread& other) const
     780             :     {
     781             :         return get_id()!=other.get_id();
     782             :     }
     783             : #endif
     784             : 
     785             :     namespace detail
     786             :     {
     787             :         struct thread_exit_function_base
     788             :         {
     789             :             virtual ~thread_exit_function_base()
     790             :             {}
     791             :             virtual void operator()()=0;
     792             :         };
     793             : 
     794             :         template<typename F>
     795             :         struct thread_exit_function:
     796             :             thread_exit_function_base
     797             :         {
     798             :             F f;
     799             : 
     800             :             thread_exit_function(F f_):
     801             :                 f(f_)
     802             :             {}
     803             : 
     804             :             void operator()()
     805             :             {
     806             :                 f();
     807             :             }
     808             :         };
     809             : 
     810             :         void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*);
     811             : //#ifndef BOOST_NO_EXCEPTIONS
     812             :         struct shared_state_base;
     813             : #if defined(BOOST_THREAD_PLATFORM_WIN32)
     814             :         inline void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
     815             :         {
     816             :           detail::thread_data_base* const current_thread_data(detail::get_current_thread_data());
     817             :           if(current_thread_data)
     818             :           {
     819             :             current_thread_data->make_ready_at_thread_exit(as);
     820             :           }
     821             :         }
     822             : #else
     823             :         void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as);
     824             : #endif
     825             : //#endif
     826             :     }
     827             : 
     828             :     namespace this_thread
     829             :     {
     830             :         template<typename F>
     831             :         void at_thread_exit(F f)
     832             :         {
     833             :             detail::thread_exit_function_base* const thread_exit_func=detail::heap_new<detail::thread_exit_function<F> >(f);
     834             :             detail::add_thread_exit_function(thread_exit_func);
     835             :         }
     836             :     }
     837             : }
     838             : 
     839             : #ifdef BOOST_MSVC
     840             : #pragma warning(pop)
     841             : #endif
     842             : 
     843             : #include <boost/config/abi_suffix.hpp>
     844             : 
     845             : #endif

Generated by: LCOV version 1.14