]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/thread/detail/thread.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / thread / detail / thread.hpp
CommitLineData
7c673cae
FG
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
92f5a8d4
TL
21#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
22#include <boost/thread/interruption.hpp>
23#endif
7c673cae
FG
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>
11fdf7f2 42#include <boost/thread/detail/platform_time.hpp>
7c673cae
FG
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
58namespace 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 void run()
119 {
120 f();
121 }
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 }
11fdf7f2 162
7c673cae
FG
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<
b32b8144 298 boost::thread_detail::is_rv<F>::value // todo as a thread_detail::is_rv
7c673cae
FG
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;
7c673cae 461 id get_id() const BOOST_NOEXCEPT;
7c673cae
FG
462
463 bool joinable() const BOOST_NOEXCEPT;
464 private:
465 bool join_noexcept();
11fdf7f2
TL
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);
7c673cae 468 public:
11fdf7f2 469 void join();
7c673cae
FG
470
471#ifdef BOOST_THREAD_USES_CHRONO
11fdf7f2
TL
472 template <class Duration>
473 bool try_join_until(const chrono::time_point<detail::internal_chrono_clock, Duration>& t)
7c673cae 474 {
11fdf7f2 475 return do_try_join_until(boost::detail::internal_platform_timepoint(t));
7c673cae 476 }
b32b8144 477
7c673cae
FG
478 template <class Clock, class Duration>
479 bool try_join_until(const chrono::time_point<Clock, Duration>& t)
480 {
11fdf7f2
TL
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 }
7c673cae
FG
490 return true;
491 }
7c673cae 492
11fdf7f2
TL
493 template <class Rep, class Period>
494 bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
7c673cae 495 {
11fdf7f2 496 return try_join_until(chrono::steady_clock::now() + rel_time);
7c673cae
FG
497 }
498#endif
7c673cae
FG
499#if defined BOOST_THREAD_USES_DATETIME
500 bool timed_join(const system_time& abs_time)
501 {
11fdf7f2
TL
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
7c673cae 514 return do_try_join_until(ts);
7c673cae 515#endif
7c673cae 516 }
7c673cae 517
7c673cae 518 template<typename TimeDuration>
11fdf7f2 519 bool timed_join(TimeDuration const& rel_time)
7c673cae 520 {
11fdf7f2
TL
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
7c673cae
FG
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
11fdf7f2 588 thread::id get_id() BOOST_NOEXCEPT;
7c673cae
FG
589#else
590 thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT;
591#endif
592
7c673cae 593#if defined BOOST_THREAD_USES_DATETIME
92f5a8d4 594 inline BOOST_SYMBOL_VISIBLE void sleep(::boost::xtime const& abs_time)
7c673cae
FG
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
11fdf7f2 713 inline thread::id thread::get_id() const BOOST_NOEXCEPT
7c673cae
FG
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
11fdf7f2 736 inline void thread::join() {
7c673cae
FG
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
11fdf7f2 745 inline bool thread::do_try_join_until(detail::internal_platform_timepoint const &timeout)
7c673cae
FG
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*);
92f5a8d4 811//#ifndef BOOST_NO_EXCEPTIONS
7c673cae
FG
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
92f5a8d4 825//#endif
7c673cae
FG
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