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
0004
0005
0006
0007
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
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
0104
0105
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
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
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
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
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
0299
0300
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
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)))
0323 #else
0324 thread_info(make_thread_info(f))
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)))
0334 #else
0335 thread_info(make_thread_info(f))
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
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;
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;
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;
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
0548
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
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
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
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