Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/thread/detail/thread.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 #ifndef BOOST_THREAD_THREAD_COMMON_HPP
0002 #define BOOST_THREAD_THREAD_COMMON_HPP
0003 // Distributed under the Boost Software License, Version 1.0. (See
0004 // accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 // (C) Copyright 2007-2010 Anthony Williams
0007 // (C) Copyright 2011-2012 Vicente J. Botet Escriba
0008 
0009 #include <boost/thread/detail/config.hpp>
0010 #include <boost/predef/platform.h>
0011 
0012 #include <boost/thread/exceptions.hpp>
0013 #ifndef BOOST_NO_IOSTREAM
0014 #include <ostream>
0015 #endif
0016 #include <boost/thread/detail/move.hpp>
0017 #include <boost/thread/mutex.hpp>
0018 #if defined BOOST_THREAD_USES_DATETIME
0019 #include <boost/thread/xtime.hpp>
0020 #endif
0021 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
0022 #include <boost/thread/interruption.hpp>
0023 #endif
0024 #include <boost/thread/detail/thread_heap_alloc.hpp>
0025 #include <boost/thread/detail/make_tuple_indices.hpp>
0026 #include <boost/thread/detail/invoke.hpp>
0027 #include <boost/thread/detail/is_convertible.hpp>
0028 #include <boost/assert.hpp>
0029 #include <list>
0030 #include <algorithm>
0031 #include <boost/core/ref.hpp>
0032 #include <boost/cstdint.hpp>
0033 #include <boost/bind/bind.hpp>
0034 #include <stdlib.h>
0035 #include <memory>
0036 #include <boost/core/enable_if.hpp>
0037 #include <boost/type_traits/remove_reference.hpp>
0038 #include <boost/io/ios_state.hpp>
0039 #include <boost/type_traits/is_same.hpp>
0040 #include <boost/type_traits/decay.hpp>
0041 #include <boost/functional/hash.hpp>
0042 #include <boost/thread/detail/platform_time.hpp>
0043 #ifdef BOOST_THREAD_USES_CHRONO
0044 #include <boost/chrono/system_clocks.hpp>
0045 #include <boost/chrono/ceil.hpp>
0046 #endif
0047 
0048 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
0049 #include <tuple>
0050 #endif
0051 #include <boost/config/abi_prefix.hpp>
0052 
0053 #ifdef BOOST_MSVC
0054 #pragma warning(push)
0055 #pragma warning(disable:4251)
0056 #endif
0057 
0058 namespace boost
0059 {
0060 
0061     namespace detail
0062     {
0063 
0064 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
0065 
0066       template<typename F, class ...ArgTypes>
0067       class thread_data:
0068           public detail::thread_data_base
0069       {
0070       public:
0071           BOOST_THREAD_NO_COPYABLE(thread_data)
0072             thread_data(BOOST_THREAD_RV_REF(F) f_, BOOST_THREAD_RV_REF(ArgTypes)... args_):
0073               fp(boost::forward<F>(f_), boost::forward<ArgTypes>(args_)...)
0074             {}
0075           template <std::size_t ...Indices>
0076           void run2(tuple_indices<Indices...>)
0077           {
0078 
0079               detail::invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
0080           }
0081           void run()
0082           {
0083               typedef typename make_tuple_indices<std::tuple_size<std::tuple<F, ArgTypes...> >::value, 1>::type index_type;
0084 
0085               run2(index_type());
0086           }
0087 
0088       private:
0089           std::tuple<typename decay<F>::type, typename decay<ArgTypes>::type...> fp;
0090       };
0091 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
0092 
0093         template<typename F>
0094         class thread_data:
0095             public detail::thread_data_base
0096         {
0097         public:
0098             BOOST_THREAD_NO_COPYABLE(thread_data)
0099 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0100               thread_data(BOOST_THREAD_RV_REF(F) f_):
0101                 f(boost::forward<F>(f_))
0102               {}
0103 // This overloading must be removed if we want the packaged_task's tests to pass.
0104 //            thread_data(F& f_):
0105 //                f(f_)
0106 //            {}
0107 #else
0108 
0109             thread_data(BOOST_THREAD_RV_REF(F) f_):
0110               f(f_)
0111             {}
0112             thread_data(F f_):
0113                 f(f_)
0114             {}
0115 #endif
0116             //thread_data() {}
0117 
0118             void run()
0119             {
0120                 f();
0121             }
0122 
0123         private:
0124             F f;
0125         };
0126 
0127         template<typename F>
0128         class thread_data<boost::reference_wrapper<F> >:
0129             public detail::thread_data_base
0130         {
0131         private:
0132             F& f;
0133         public:
0134             BOOST_THREAD_NO_COPYABLE(thread_data)
0135             thread_data(boost::reference_wrapper<F> f_):
0136                 f(f_)
0137             {}
0138             void run()
0139             {
0140                 f();
0141             }
0142         };
0143 
0144         template<typename F>
0145         class thread_data<const boost::reference_wrapper<F> >:
0146             public detail::thread_data_base
0147         {
0148         private:
0149             F& f;
0150         public:
0151             BOOST_THREAD_NO_COPYABLE(thread_data)
0152             thread_data(const boost::reference_wrapper<F> f_):
0153                 f(f_)
0154             {}
0155             void run()
0156             {
0157                 f();
0158             }
0159         };
0160 #endif
0161     }
0162 
0163     class BOOST_THREAD_DECL thread
0164     {
0165     public:
0166       typedef thread_attributes attributes;
0167 
0168       BOOST_THREAD_MOVABLE_ONLY(thread)
0169     private:
0170 
0171         struct dummy;
0172 
0173         void release_handle();
0174 
0175         detail::thread_data_ptr thread_info;
0176 
0177     private:
0178         bool start_thread_noexcept();
0179         bool start_thread_noexcept(const attributes& attr);
0180         void start_thread()
0181         {
0182           if (!start_thread_noexcept())
0183           {
0184             boost::throw_exception(thread_resource_error());
0185           }
0186         }
0187         void start_thread(const attributes& attr)
0188         {
0189           if (!start_thread_noexcept(attr))
0190           {
0191             boost::throw_exception(thread_resource_error());
0192           }
0193         }
0194 
0195         explicit thread(detail::thread_data_ptr data);
0196 
0197         detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const;
0198 
0199 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0200 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
0201         template<typename F, class ...ArgTypes>
0202         static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
0203         {
0204             return detail::thread_data_ptr(detail::heap_new<
0205                   detail::thread_data<typename boost::remove_reference<F>::type, ArgTypes...>
0206                   >(
0207                     boost::forward<F>(f), boost::forward<ArgTypes>(args)...
0208                   )
0209                 );
0210         }
0211 #else
0212         template<typename F>
0213         static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
0214         {
0215             return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >(
0216                 boost::forward<F>(f)));
0217         }
0218 #endif
0219         static inline detail::thread_data_ptr make_thread_info(void (*f)())
0220         {
0221             return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(
0222                 boost::forward<void(*)()>(f)));
0223         }
0224 #else
0225         template<typename F>
0226         static inline detail::thread_data_ptr make_thread_info(F f
0227             , typename disable_if_c<
0228                 //boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value ||
0229                 is_same<typename decay<F>::type, thread>::value,
0230                 dummy* >::type=0
0231                 )
0232         {
0233             return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
0234         }
0235         template<typename F>
0236         static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
0237         {
0238             return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
0239         }
0240 
0241 #endif
0242     public:
0243 #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
0244 #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
0245         thread(const volatile thread&);
0246 #endif
0247 #endif
0248         thread() BOOST_NOEXCEPT;
0249         ~thread()
0250         {
0251 
0252     #if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
0253           if (joinable()) {
0254             std::terminate();
0255           }
0256     #else
0257             detach();
0258     #endif
0259         }
0260 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0261         template <
0262           class F
0263         >
0264         explicit thread(BOOST_THREAD_RV_REF(F) f
0265         //, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
0266         ):
0267           thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
0268         {
0269             start_thread();
0270         }
0271         template <
0272           class F
0273         >
0274         thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f):
0275           thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
0276         {
0277             start_thread(attrs);
0278         }
0279 
0280 #else
0281 #ifdef BOOST_NO_SFINAE
0282         template <class F>
0283         explicit thread(F f):
0284             thread_info(make_thread_info(f))
0285         {
0286             start_thread();
0287         }
0288         template <class F>
0289         thread(attributes const& attrs, F f):
0290             thread_info(make_thread_info(f))
0291         {
0292             start_thread(attrs);
0293         }
0294 #else
0295         template <class F>
0296         explicit thread(F f
0297         , typename disable_if_c<
0298         boost::thread_detail::is_rv<F>::value // todo as a thread_detail::is_rv
0299         //boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value
0300             //|| is_same<typename decay<F>::type, thread>::value
0301            , dummy* >::type=0
0302         ):
0303             thread_info(make_thread_info(f))
0304         {
0305             start_thread();
0306         }
0307         template <class F>
0308         thread(attributes const& attrs, F f
0309             , typename disable_if<boost::thread_detail::is_rv<F>, dummy* >::type=0
0310             //, typename disable_if<boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0
0311         ):
0312             thread_info(make_thread_info(f))
0313         {
0314             start_thread(attrs);
0315         }
0316 #endif
0317         template <class F>
0318         explicit thread(BOOST_THREAD_RV_REF(F) f
0319         , typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
0320         ):
0321 #ifdef BOOST_THREAD_USES_MOVE
0322         thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
0323 #else
0324         thread_info(make_thread_info(f)) // todo : Add forward
0325 #endif
0326         {
0327             start_thread();
0328         }
0329 
0330         template <class F>
0331         thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f):
0332 #ifdef BOOST_THREAD_USES_MOVE
0333             thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
0334 #else
0335             thread_info(make_thread_info(f)) // todo : Add forward
0336 #endif
0337         {
0338             start_thread(attrs);
0339         }
0340 #endif
0341         thread(BOOST_THREAD_RV_REF(thread) x) BOOST_NOEXCEPT
0342         {
0343             thread_info=BOOST_THREAD_RV(x).thread_info;
0344             BOOST_THREAD_RV(x).thread_info.reset();
0345         }
0346 #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
0347 #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
0348         thread& operator=(thread x)
0349         {
0350             swap(x);
0351             return *this;
0352         }
0353 #endif
0354 #endif
0355 
0356         thread& operator=(BOOST_THREAD_RV_REF(thread) other) BOOST_NOEXCEPT
0357         {
0358 
0359 #if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
0360             if (joinable()) std::terminate();
0361 #else
0362             detach();
0363 #endif
0364             thread_info=BOOST_THREAD_RV(other).thread_info;
0365             BOOST_THREAD_RV(other).thread_info.reset();
0366             return *this;
0367         }
0368 
0369 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
0370         template <class F, class Arg, class ...Args>
0371         thread(F&& f, Arg&& arg, Args&&... args) :
0372           thread_info(make_thread_info(
0373               thread_detail::decay_copy(boost::forward<F>(f)),
0374               thread_detail::decay_copy(boost::forward<Arg>(arg)),
0375               thread_detail::decay_copy(boost::forward<Args>(args))...)
0376           )
0377 
0378         {
0379           start_thread();
0380         }
0381         template <class F, class Arg, class ...Args>
0382         thread(attributes const& attrs, F&& f, Arg&& arg, Args&&... args) :
0383           thread_info(make_thread_info(
0384               thread_detail::decay_copy(boost::forward<F>(f)),
0385               thread_detail::decay_copy(boost::forward<Arg>(arg)),
0386               thread_detail::decay_copy(boost::forward<Args>(args))...)
0387           )
0388 
0389         {
0390           start_thread(attrs);
0391         }
0392 #else
0393         template <class F,class A1>
0394         thread(F f,A1 a1,typename disable_if<boost::thread_detail::is_convertible<F&,thread_attributes >, dummy* >::type=0):
0395             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1)))
0396         {
0397             start_thread();
0398         }
0399         template <class F,class A1,class A2>
0400         thread(F f,A1 a1,A2 a2):
0401             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2)))
0402         {
0403             start_thread();
0404         }
0405 
0406         template <class F,class A1,class A2,class A3>
0407         thread(F f,A1 a1,A2 a2,A3 a3):
0408             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3)))
0409         {
0410             start_thread();
0411         }
0412 
0413         template <class F,class A1,class A2,class A3,class A4>
0414         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4):
0415             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4)))
0416         {
0417             start_thread();
0418         }
0419 
0420         template <class F,class A1,class A2,class A3,class A4,class A5>
0421         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5):
0422             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5)))
0423         {
0424             start_thread();
0425         }
0426 
0427         template <class F,class A1,class A2,class A3,class A4,class A5,class A6>
0428         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6):
0429             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6)))
0430         {
0431             start_thread();
0432         }
0433 
0434         template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7>
0435         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7):
0436             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7)))
0437         {
0438             start_thread();
0439         }
0440 
0441         template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8>
0442         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8):
0443             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8)))
0444         {
0445             start_thread();
0446         }
0447 
0448         template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8,class A9>
0449         thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9):
0450             thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8,a9)))
0451         {
0452             start_thread();
0453         }
0454 #endif
0455         void swap(thread& x) BOOST_NOEXCEPT
0456         {
0457             thread_info.swap(x.thread_info);
0458         }
0459 
0460         class id;
0461         id get_id() const BOOST_NOEXCEPT;
0462 
0463         bool joinable() const BOOST_NOEXCEPT;
0464     private:
0465         bool join_noexcept();
0466         bool do_try_join_until_noexcept(detail::internal_platform_timepoint const &timeout, bool& res);
0467         bool do_try_join_until(detail::internal_platform_timepoint const &timeout);
0468     public:
0469         void join();
0470 
0471 #ifdef BOOST_THREAD_USES_CHRONO
0472         template <class Duration>
0473         bool try_join_until(const chrono::time_point<detail::internal_chrono_clock, Duration>& t)
0474         {
0475           return do_try_join_until(boost::detail::internal_platform_timepoint(t));
0476         }
0477 
0478         template <class Clock, class Duration>
0479         bool try_join_until(const chrono::time_point<Clock, Duration>& t)
0480         {
0481           typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
0482           common_duration d(t - Clock::now());
0483           d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
0484           while ( ! try_join_until(detail::internal_chrono_clock::now() + d) )
0485           {
0486             d = t - Clock::now();
0487             if ( d <= common_duration::zero() ) return false; // timeout occurred
0488             d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
0489           }
0490           return true;
0491         }
0492 
0493         template <class Rep, class Period>
0494         bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
0495         {
0496           return try_join_until(chrono::steady_clock::now() + rel_time);
0497         }
0498 #endif
0499 #if defined BOOST_THREAD_USES_DATETIME
0500         bool timed_join(const system_time& abs_time)
0501         {
0502           const detail::real_platform_timepoint ts(abs_time);
0503 #if defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
0504           detail::platform_duration d(ts - detail::real_platform_clock::now());
0505           d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
0506           while ( ! do_try_join_until(detail::internal_platform_clock::now() + d) )
0507           {
0508             d = ts - detail::real_platform_clock::now();
0509             if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
0510             d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
0511           }
0512           return true;
0513 #else
0514           return do_try_join_until(ts);
0515 #endif
0516         }
0517 
0518         template<typename TimeDuration>
0519         bool timed_join(TimeDuration const& rel_time)
0520         {
0521           detail::platform_duration d(rel_time);
0522 #if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
0523           const detail::mono_platform_timepoint ts(detail::mono_platform_clock::now() + d);
0524           d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
0525           while ( ! do_try_join_until(detail::internal_platform_clock::now() + d) )
0526           {
0527             d = ts - detail::mono_platform_clock::now();
0528             if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
0529             d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
0530           }
0531           return true;
0532 #else
0533           return do_try_join_until(detail::internal_platform_clock::now() + d);
0534 #endif
0535         }
0536 #endif
0537         void detach();
0538 
0539         static unsigned hardware_concurrency() BOOST_NOEXCEPT;
0540         static unsigned physical_concurrency() BOOST_NOEXCEPT;
0541 
0542 #define BOOST_THREAD_DEFINES_THREAD_NATIVE_HANDLE
0543         typedef detail::thread_data_base::native_handle_type native_handle_type;
0544         native_handle_type native_handle();
0545 
0546 #if defined BOOST_THREAD_PROVIDES_THREAD_EQ
0547         // Use thread::id when comparisions are needed
0548         // backwards compatibility
0549         bool operator==(const thread& other) const;
0550         bool operator!=(const thread& other) const;
0551 #endif
0552 #if defined BOOST_THREAD_USES_DATETIME
0553         static inline void yield() BOOST_NOEXCEPT
0554         {
0555             this_thread::yield();
0556         }
0557 
0558         static inline void sleep(const system_time& xt)
0559         {
0560             this_thread::sleep(xt);
0561         }
0562 #endif
0563 
0564 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
0565         // extensions
0566         void interrupt();
0567         bool interruption_requested() const BOOST_NOEXCEPT;
0568 #endif
0569     };
0570 
0571     inline void swap(thread& lhs,thread& rhs) BOOST_NOEXCEPT
0572     {
0573         return lhs.swap(rhs);
0574     }
0575 
0576 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0577     inline thread&& move(thread& t) BOOST_NOEXCEPT
0578     {
0579         return static_cast<thread&&>(t);
0580     }
0581 #endif
0582 
0583     BOOST_THREAD_DCL_MOVABLE(thread)
0584 
0585     namespace this_thread
0586     {
0587 #ifdef BOOST_THREAD_PLATFORM_PTHREAD
0588         thread::id get_id() BOOST_NOEXCEPT;
0589 #else
0590         thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT;
0591 #endif
0592 
0593 #if defined BOOST_THREAD_USES_DATETIME
0594         inline BOOST_SYMBOL_VISIBLE void sleep(::boost::xtime const& abs_time)
0595         {
0596             sleep(system_time(abs_time));
0597         }
0598 #endif
0599     }
0600 
0601     class BOOST_SYMBOL_VISIBLE thread::id
0602     {
0603     private:
0604     
0605     #if !defined(BOOST_EMBTC)
0606       
0607         friend inline
0608         std::size_t
0609         hash_value(const thread::id &v)
0610         {
0611 #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
0612           return hash_value(v.thread_data);
0613 #else
0614           return hash_value(v.thread_data.get());
0615 #endif
0616         }
0617 
0618     #else
0619       
0620         friend
0621         std::size_t
0622         hash_value(const thread::id &v);
0623 
0624     #endif
0625       
0626 #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
0627 #if defined(BOOST_THREAD_PLATFORM_WIN32)
0628         typedef unsigned int data;
0629 #else
0630         typedef thread::native_handle_type data;
0631 #endif
0632 #else
0633         typedef detail::thread_data_ptr data;
0634 #endif
0635         data thread_data;
0636 
0637         id(data thread_data_):
0638             thread_data(thread_data_)
0639         {}
0640         friend class thread;
0641         friend id BOOST_THREAD_DECL this_thread::get_id() BOOST_NOEXCEPT;
0642     public:
0643         id() BOOST_NOEXCEPT:
0644 #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
0645         thread_data(0)
0646 #else
0647         thread_data()
0648 #endif
0649         {}
0650 
0651         bool operator==(const id& y) const BOOST_NOEXCEPT
0652         {
0653             return thread_data==y.thread_data;
0654         }
0655 
0656         bool operator!=(const id& y) const BOOST_NOEXCEPT
0657         {
0658             return thread_data!=y.thread_data;
0659         }
0660 
0661         bool operator<(const id& y) const BOOST_NOEXCEPT
0662         {
0663             return thread_data<y.thread_data;
0664         }
0665 
0666         bool operator>(const id& y) const BOOST_NOEXCEPT
0667         {
0668             return y.thread_data<thread_data;
0669         }
0670 
0671         bool operator<=(const id& y) const BOOST_NOEXCEPT
0672         {
0673             return !(y.thread_data<thread_data);
0674         }
0675 
0676         bool operator>=(const id& y) const BOOST_NOEXCEPT
0677         {
0678             return !(thread_data<y.thread_data);
0679         }
0680 
0681 #ifndef BOOST_NO_IOSTREAM
0682 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0683         template<class charT, class traits>
0684         friend BOOST_SYMBOL_VISIBLE
0685   std::basic_ostream<charT, traits>&
0686         operator<<(std::basic_ostream<charT, traits>& os, const id& x)
0687         {
0688             if(x.thread_data)
0689             {
0690                 io::ios_flags_saver  ifs( os );
0691                 return os<< std::hex << x.thread_data;
0692             }
0693             else
0694             {
0695                 return os<<"{Not-any-thread}";
0696             }
0697         }
0698 #else
0699         template<class charT, class traits>
0700         BOOST_SYMBOL_VISIBLE
0701   std::basic_ostream<charT, traits>&
0702         print(std::basic_ostream<charT, traits>& os) const
0703         {
0704             if(thread_data)
0705             {
0706               io::ios_flags_saver  ifs( os );
0707               return os<< std::hex << thread_data;
0708             }
0709             else
0710             {
0711                 return os<<"{Not-any-thread}";
0712             }
0713         }
0714 
0715 #endif
0716 #endif
0717     };
0718     
0719 #if defined(BOOST_EMBTC)
0720 
0721         inline
0722         std::size_t
0723         hash_value(const thread::id &v)
0724         {
0725 #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
0726           return hash_value(v.thread_data);
0727 #else
0728           return hash_value(v.thread_data.get());
0729 #endif
0730         }
0731 
0732 #endif
0733 
0734 #ifdef BOOST_THREAD_PLATFORM_PTHREAD
0735     inline thread::id thread::get_id() const BOOST_NOEXCEPT
0736     {
0737     #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
0738         return const_cast<thread*>(this)->native_handle();
0739     #else
0740         detail::thread_data_ptr const local_thread_info=(get_thread_info)();
0741         return (local_thread_info? id(local_thread_info) : id());
0742     #endif
0743     }
0744 
0745     namespace this_thread
0746     {
0747         inline thread::id get_id() BOOST_NOEXCEPT
0748         {
0749         #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
0750              return pthread_self();
0751         #else
0752             boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data();
0753             return (thread_info?thread::id(thread_info->shared_from_this()):thread::id());
0754         #endif
0755         }
0756     }
0757 #endif
0758     inline void thread::join() {
0759         if (this_thread::get_id() == get_id())
0760           boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));
0761 
0762         BOOST_THREAD_VERIFY_PRECONDITION( join_noexcept(),
0763             thread_resource_error(static_cast<int>(system::errc::invalid_argument), "boost thread: thread not joinable")
0764         );
0765     }
0766 
0767     inline bool thread::do_try_join_until(detail::internal_platform_timepoint const &timeout)
0768     {
0769         if (this_thread::get_id() == get_id())
0770           boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));
0771         bool res;
0772         if (do_try_join_until_noexcept(timeout, res))
0773         {
0774           return res;
0775         }
0776         else
0777         {
0778           BOOST_THREAD_THROW_ELSE_RETURN(
0779             (thread_resource_error(static_cast<int>(system::errc::invalid_argument), "boost thread: thread not joinable")),
0780             false
0781           );
0782         }
0783     }
0784 
0785 #if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
0786     template<class charT, class traits>
0787     BOOST_SYMBOL_VISIBLE
0788     std::basic_ostream<charT, traits>&
0789     operator<<(std::basic_ostream<charT, traits>& os, const thread::id& x)
0790     {
0791         return x.print(os);
0792     }
0793 #endif
0794 
0795 #if defined BOOST_THREAD_PROVIDES_THREAD_EQ
0796     inline bool thread::operator==(const thread& other) const
0797     {
0798         return get_id()==other.get_id();
0799     }
0800 
0801     inline bool thread::operator!=(const thread& other) const
0802     {
0803         return get_id()!=other.get_id();
0804     }
0805 #endif
0806 
0807     namespace detail
0808     {
0809         struct thread_exit_function_base
0810         {
0811             virtual ~thread_exit_function_base()
0812             {}
0813             virtual void operator()()=0;
0814         };
0815 
0816         template<typename F>
0817         struct thread_exit_function:
0818             thread_exit_function_base
0819         {
0820             F f;
0821 
0822             thread_exit_function(F f_):
0823                 f(f_)
0824             {}
0825 
0826             void operator()()
0827             {
0828                 f();
0829             }
0830         };
0831 
0832         void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*);
0833 //#ifndef BOOST_NO_EXCEPTIONS
0834         struct shared_state_base;
0835 #if defined(BOOST_THREAD_PLATFORM_WIN32)
0836         inline void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
0837         {
0838           detail::thread_data_base* const current_thread_data(detail::get_current_thread_data());
0839           if(current_thread_data)
0840           {
0841             current_thread_data->make_ready_at_thread_exit(as);
0842           }
0843         }
0844 #else
0845         void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as);
0846 #endif
0847 //#endif
0848     }
0849 
0850     namespace this_thread
0851     {
0852         template<typename F>
0853         void at_thread_exit(F f)
0854         {
0855             detail::thread_exit_function_base* const thread_exit_func=detail::heap_new<detail::thread_exit_function<F> >(f);
0856             detail::add_thread_exit_function(thread_exit_func);
0857         }
0858     }
0859 }
0860 
0861 #ifdef BOOST_MSVC
0862 #pragma warning(pop)
0863 #endif
0864 
0865 #include <boost/config/abi_suffix.hpp>
0866 
0867 #endif