annotate DEPENDENCIES/generic/include/boost/thread/detail/thread.hpp @ 16:2665513ce2d3

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