annotate DEPENDENCIES/generic/include/boost/thread/detail/thread.hpp @ 133:4acb5d8d80b6 tip

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