1 // Distributed under the Boost Software License, Version 1.0. (See 2 // accompanying file LICENSE_1_0.txt or copy at 3 // http://www.boost.org/LICENSE_1_0.txt) 4 // (C) Copyright 2007 Anthony Williams 5 // (C) Copyright 2011-2012 Vicente J. Botet Escriba 6 7 #ifndef BOOST_THREAD_LOCK_TYPES_HPP 8 #define BOOST_THREAD_LOCK_TYPES_HPP 9 10 #include <boost/thread/detail/config.hpp> 11 #include <boost/thread/detail/move.hpp> 12 #include <boost/thread/exceptions.hpp> 13 #include <boost/thread/lock_options.hpp> 14 #include <boost/thread/lockable_traits.hpp> 15 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS 16 #include <boost/thread/is_locked_by_this_thread.hpp> 17 #endif 18 #include <boost/thread/thread_time.hpp> 19 20 #include <boost/assert.hpp> 21 #ifdef BOOST_THREAD_USES_CHRONO 22 #include <boost/chrono/time_point.hpp> 23 #include <boost/chrono/duration.hpp> 24 #endif 25 #include <boost/detail/workaround.hpp> 26 27 #include <boost/config/abi_prefix.hpp> 28 29 namespace boost 30 { 31 struct xtime; 32 33 template <typename Mutex> 34 class shared_lock; 35 36 template <typename Mutex> 37 class upgrade_lock; 38 39 template <typename Mutex> 40 class unique_lock; 41 42 namespace detail 43 { 44 template <typename Mutex> 45 class try_lock_wrapper; 46 } 47 48 #ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES 49 namespace sync 50 { 51 template<typename T> 52 struct is_basic_lockable<unique_lock<T> > 53 { 54 BOOST_STATIC_CONSTANT(bool, value = true); 55 }; 56 template<typename T> 57 struct is_lockable<unique_lock<T> > 58 { 59 BOOST_STATIC_CONSTANT(bool, value = true); 60 }; 61 62 template<typename T> 63 struct is_basic_lockable<shared_lock<T> > 64 { 65 BOOST_STATIC_CONSTANT(bool, value = true); 66 }; 67 template<typename T> 68 struct is_lockable<shared_lock<T> > 69 { 70 BOOST_STATIC_CONSTANT(bool, value = true); 71 }; 72 73 template<typename T> 74 struct is_basic_lockable<upgrade_lock<T> > 75 { 76 BOOST_STATIC_CONSTANT(bool, value = true); 77 }; 78 template<typename T> 79 struct is_lockable<upgrade_lock<T> > 80 { 81 BOOST_STATIC_CONSTANT(bool, value = true); 82 }; 83 84 template<typename T> 85 struct is_basic_lockable<detail::try_lock_wrapper<T> > 86 { 87 BOOST_STATIC_CONSTANT(bool, value = true); 88 }; 89 template<typename T> 90 struct is_lockable<detail::try_lock_wrapper<T> > 91 { 92 BOOST_STATIC_CONSTANT(bool, value = true); 93 }; 94 } 95 #endif 96 97 98 template <typename Mutex> 99 class unique_lock 100 { 101 private: 102 Mutex* m; 103 bool is_locked; 104 105 private: 106 explicit unique_lock(upgrade_lock<Mutex>&); 107 unique_lock& operator=(upgrade_lock<Mutex>& other); 108 public: 109 typedef Mutex mutex_type; 110 BOOST_THREAD_MOVABLE_ONLY( unique_lock) 111 112 #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF. 113 #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) 114 unique_lock(const volatile unique_lock&); 115 #endif 116 #endif unique_lock()117 unique_lock()BOOST_NOEXCEPT : 118 m(0),is_locked(false) 119 {} 120 unique_lock(Mutex & m_)121 explicit unique_lock(Mutex& m_) : 122 m(&m_), is_locked(false) 123 { 124 lock(); 125 } unique_lock(Mutex & m_,adopt_lock_t)126 unique_lock(Mutex& m_, adopt_lock_t) : 127 m(&m_), is_locked(true) 128 { 129 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS 130 BOOST_ASSERT(is_locked_by_this_thread(m)); 131 #endif 132 } unique_lock(Mutex & m_,defer_lock_t)133 unique_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT: 134 m(&m_),is_locked(false) 135 {} unique_lock(Mutex & m_,try_to_lock_t)136 unique_lock(Mutex& m_, try_to_lock_t) : 137 m(&m_), is_locked(false) 138 { 139 try_lock(); 140 } 141 #if defined BOOST_THREAD_USES_DATETIME 142 template<typename TimeDuration> unique_lock(Mutex & m_,TimeDuration const & target_time)143 unique_lock(Mutex& m_,TimeDuration const& target_time): 144 m(&m_),is_locked(false) 145 { 146 timed_lock(target_time); 147 } unique_lock(Mutex & m_,system_time const & target_time)148 unique_lock(Mutex& m_,system_time const& target_time): 149 m(&m_),is_locked(false) 150 { 151 timed_lock(target_time); 152 } 153 #endif 154 #ifdef BOOST_THREAD_USES_CHRONO 155 template <class Clock, class Duration> unique_lock(Mutex & mtx,const chrono::time_point<Clock,Duration> & t)156 unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t) 157 : m(&mtx), is_locked(mtx.try_lock_until(t)) 158 { 159 } 160 template <class Rep, class Period> unique_lock(Mutex & mtx,const chrono::duration<Rep,Period> & d)161 unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d) 162 : m(&mtx), is_locked(mtx.try_lock_for(d)) 163 { 164 } 165 #endif 166 unique_lock(BOOST_THREAD_RV_REF (unique_lock)other)167 unique_lock(BOOST_THREAD_RV_REF(unique_lock) other) BOOST_NOEXCEPT: 168 m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) 169 { 170 BOOST_THREAD_RV(other).is_locked=false; 171 BOOST_THREAD_RV(other).m=0; 172 } 173 174 BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other); 175 176 #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION 177 //std-2104 unique_lock move-assignment should not be noexcept operator =(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)178 unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT 179 { 180 unique_lock temp(::boost::move(other)); 181 swap(temp); 182 return *this; 183 } 184 #endif 185 186 //std-2104 unique_lock move-assignment should not be noexcept operator =(BOOST_THREAD_RV_REF (unique_lock)other)187 unique_lock& operator=(BOOST_THREAD_RV_REF(unique_lock) other) //BOOST_NOEXCEPT 188 { 189 unique_lock temp(::boost::move(other)); 190 swap(temp); 191 return *this; 192 } 193 #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF. 194 #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) 195 unique_lock& operator=(unique_lock<Mutex> other) 196 { 197 swap(other); 198 return *this; 199 } 200 #endif // BOOST_WORKAROUND 201 #endif 202 203 // Conversion from upgrade locking unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,try_to_lock_t)204 unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, try_to_lock_t) 205 : m(0),is_locked(false) 206 { 207 if (BOOST_THREAD_RV(ul).owns_lock()) 208 { 209 if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock()) 210 { 211 m = BOOST_THREAD_RV(ul).release(); 212 is_locked = true; 213 } 214 } 215 else 216 { 217 m = BOOST_THREAD_RV(ul).release(); 218 } 219 } 220 221 #ifdef BOOST_THREAD_USES_CHRONO 222 template <class Clock, class Duration> unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,const chrono::time_point<Clock,Duration> & abs_time)223 unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, 224 const chrono::time_point<Clock, Duration>& abs_time) 225 : m(0),is_locked(false) 226 { 227 if (BOOST_THREAD_RV(ul).owns_lock()) 228 { 229 if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_until(abs_time)) 230 { 231 m = BOOST_THREAD_RV(ul).release(); 232 is_locked = true; 233 } 234 } 235 else 236 { 237 m = BOOST_THREAD_RV(ul).release(); 238 } 239 } 240 241 template <class Rep, class Period> unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,const chrono::duration<Rep,Period> & rel_time)242 unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, 243 const chrono::duration<Rep, Period>& rel_time) 244 : m(0),is_locked(false) 245 { 246 if (BOOST_THREAD_RV(ul).owns_lock()) 247 { 248 if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_for(rel_time)) 249 { 250 m = BOOST_THREAD_RV(ul).release(); 251 is_locked = true; 252 } 253 } 254 else 255 { 256 m = BOOST_THREAD_RV(ul).release(); 257 } 258 } 259 #endif 260 261 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS 262 // Conversion from shared locking unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,try_to_lock_t)263 unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t) 264 : m(0),is_locked(false) 265 { 266 if (BOOST_THREAD_RV(sl).owns_lock()) 267 { 268 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock()) 269 { 270 m = BOOST_THREAD_RV(sl).release(); 271 is_locked = true; 272 } 273 } 274 else 275 { 276 m = BOOST_THREAD_RV(sl).release(); 277 } 278 } 279 280 #ifdef BOOST_THREAD_USES_CHRONO 281 template <class Clock, class Duration> unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,const chrono::time_point<Clock,Duration> & abs_time)282 unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, 283 const chrono::time_point<Clock, Duration>& abs_time) 284 : m(0),is_locked(false) 285 { 286 if (BOOST_THREAD_RV(sl).owns_lock()) 287 { 288 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_until(abs_time)) 289 { 290 m = BOOST_THREAD_RV(sl).release(); 291 is_locked = true; 292 } 293 } 294 else 295 { 296 m = BOOST_THREAD_RV(sl).release(); 297 } 298 } 299 300 template <class Rep, class Period> unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,const chrono::duration<Rep,Period> & rel_time)301 unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, 302 const chrono::duration<Rep, Period>& rel_time) 303 : m(0),is_locked(false) 304 { 305 if (BOOST_THREAD_RV(sl).owns_lock()) 306 { 307 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_for(rel_time)) 308 { 309 m = BOOST_THREAD_RV(sl).release(); 310 is_locked = true; 311 } 312 } 313 else 314 { 315 m = BOOST_THREAD_RV(sl).release(); 316 } 317 } 318 #endif // BOOST_THREAD_USES_CHRONO 319 #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS 320 swap(unique_lock & other)321 void swap(unique_lock& other)BOOST_NOEXCEPT 322 { 323 std::swap(m,other.m); 324 std::swap(is_locked,other.is_locked); 325 } 326 ~unique_lock()327 ~unique_lock() 328 { 329 if (owns_lock()) 330 { 331 m->unlock(); 332 } 333 } lock()334 void lock() 335 { 336 if (m == 0) 337 { 338 boost::throw_exception( 339 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex")); 340 } 341 if (owns_lock()) 342 { 343 boost::throw_exception( 344 boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex")); 345 } 346 m->lock(); 347 is_locked = true; 348 } try_lock()349 bool try_lock() 350 { 351 if (m == 0) 352 { 353 boost::throw_exception( 354 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex")); 355 } 356 if (owns_lock()) 357 { 358 boost::throw_exception( 359 boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex")); 360 } 361 is_locked = m->try_lock(); 362 return is_locked; 363 } 364 #if defined BOOST_THREAD_USES_DATETIME 365 template<typename TimeDuration> timed_lock(TimeDuration const & relative_time)366 bool timed_lock(TimeDuration const& relative_time) 367 { 368 if(m==0) 369 { 370 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex")); 371 } 372 if(owns_lock()) 373 { 374 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex")); 375 } 376 is_locked=m->timed_lock(relative_time); 377 return is_locked; 378 } 379 timed_lock(::boost::system_time const & absolute_time)380 bool timed_lock(::boost::system_time const& absolute_time) 381 { 382 if(m==0) 383 { 384 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex")); 385 } 386 if(owns_lock()) 387 { 388 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex")); 389 } 390 is_locked=m->timed_lock(absolute_time); 391 return is_locked; 392 } timed_lock(::boost::xtime const & absolute_time)393 bool timed_lock(::boost::xtime const& absolute_time) 394 { 395 if(m==0) 396 { 397 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex")); 398 } 399 if(owns_lock()) 400 { 401 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex")); 402 } 403 is_locked=m->timed_lock(absolute_time); 404 return is_locked; 405 } 406 #endif 407 #ifdef BOOST_THREAD_USES_CHRONO 408 409 template <class Rep, class Period> try_lock_for(const chrono::duration<Rep,Period> & rel_time)410 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) 411 { 412 if(m==0) 413 { 414 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex")); 415 } 416 if(owns_lock()) 417 { 418 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex")); 419 } 420 is_locked=m->try_lock_for(rel_time); 421 return is_locked; 422 } 423 template <class Clock, class Duration> try_lock_until(const chrono::time_point<Clock,Duration> & abs_time)424 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) 425 { 426 if(m==0) 427 { 428 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex")); 429 } 430 if(owns_lock()) 431 { 432 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex")); 433 } 434 is_locked=m->try_lock_until(abs_time); 435 return is_locked; 436 } 437 #endif 438 unlock()439 void unlock() 440 { 441 if (m == 0) 442 { 443 boost::throw_exception( 444 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex")); 445 } 446 if (!owns_lock()) 447 { 448 boost::throw_exception( 449 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock doesn't own the mutex")); 450 } 451 m->unlock(); 452 is_locked = false; 453 } 454 455 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) 456 typedef void (unique_lock::*bool_type)(); operator bool_type() const457 operator bool_type() const BOOST_NOEXCEPT 458 { 459 return is_locked?&unique_lock::lock:0; 460 } operator !() const461 bool operator!() const BOOST_NOEXCEPT 462 { 463 return !owns_lock(); 464 } 465 #else operator bool() const466 explicit operator bool() const BOOST_NOEXCEPT 467 { 468 return owns_lock(); 469 } 470 #endif owns_lock() const471 bool owns_lock() const BOOST_NOEXCEPT 472 { 473 return is_locked; 474 } 475 mutex() const476 Mutex* mutex() const BOOST_NOEXCEPT 477 { 478 return m; 479 } 480 release()481 Mutex* release()BOOST_NOEXCEPT 482 { 483 Mutex* const res=m; 484 m=0; 485 is_locked=false; 486 return res; 487 } 488 489 friend class shared_lock<Mutex> ; 490 friend class upgrade_lock<Mutex> ; 491 }; 492 493 template<typename Mutex> swap(unique_lock<Mutex> & lhs,unique_lock<Mutex> & rhs)494 void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs) 495 BOOST_NOEXCEPT 496 { 497 lhs.swap(rhs); 498 } 499 500 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END 501 502 template<typename Mutex> 503 class shared_lock 504 { 505 protected: 506 Mutex* m; 507 bool is_locked; 508 509 public: 510 typedef Mutex mutex_type; 511 BOOST_THREAD_MOVABLE_ONLY(shared_lock) 512 shared_lock()513 shared_lock() BOOST_NOEXCEPT: 514 m(0),is_locked(false) 515 {} 516 shared_lock(Mutex & m_)517 explicit shared_lock(Mutex& m_): 518 m(&m_),is_locked(false) 519 { 520 lock(); 521 } shared_lock(Mutex & m_,adopt_lock_t)522 shared_lock(Mutex& m_,adopt_lock_t): 523 m(&m_),is_locked(true) 524 { 525 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS 526 BOOST_ASSERT(is_locked_by_this_thread(m)); 527 #endif 528 } shared_lock(Mutex & m_,defer_lock_t)529 shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT: 530 m(&m_),is_locked(false) 531 {} shared_lock(Mutex & m_,try_to_lock_t)532 shared_lock(Mutex& m_,try_to_lock_t): 533 m(&m_),is_locked(false) 534 { 535 try_lock(); 536 } 537 #if defined BOOST_THREAD_USES_DATETIME shared_lock(Mutex & m_,system_time const & target_time)538 shared_lock(Mutex& m_,system_time const& target_time): 539 m(&m_),is_locked(false) 540 { 541 timed_lock(target_time); 542 } 543 #endif 544 #ifdef BOOST_THREAD_USES_CHRONO 545 template <class Clock, class Duration> shared_lock(Mutex & mtx,const chrono::time_point<Clock,Duration> & t)546 shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t) 547 : m(&mtx), is_locked(mtx.try_lock_shared_until(t)) 548 { 549 } 550 template <class Rep, class Period> shared_lock(Mutex & mtx,const chrono::duration<Rep,Period> & d)551 shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d) 552 : m(&mtx), is_locked(mtx.try_lock_shared_for(d)) 553 { 554 } 555 #endif 556 shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other)557 shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT: 558 m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) 559 { 560 BOOST_THREAD_RV(other).is_locked=false; 561 BOOST_THREAD_RV(other).m=0; 562 } 563 shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)564 BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other): 565 m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) 566 { 567 if(is_locked) 568 { 569 m->unlock_and_lock_shared(); 570 } 571 BOOST_THREAD_RV(other).is_locked=false; 572 BOOST_THREAD_RV(other).m=0; 573 } 574 shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)575 BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other): 576 m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) 577 { 578 if(is_locked) 579 { 580 m->unlock_upgrade_and_lock_shared(); 581 } 582 BOOST_THREAD_RV(other).is_locked=false; 583 BOOST_THREAD_RV(other).m=0; 584 } 585 586 //std-2104 unique_lock move-assignment should not be noexcept operator =(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other)587 shared_lock& operator=(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT 588 { 589 shared_lock temp(::boost::move(other)); 590 swap(temp); 591 return *this; 592 } 593 #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION operator =(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)594 shared_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) 595 { 596 shared_lock temp(::boost::move(other)); 597 swap(temp); 598 return *this; 599 } 600 operator =(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)601 shared_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) 602 { 603 shared_lock temp(::boost::move(other)); 604 swap(temp); 605 return *this; 606 } 607 #endif 608 swap(shared_lock & other)609 void swap(shared_lock& other) BOOST_NOEXCEPT 610 { 611 std::swap(m,other.m); 612 std::swap(is_locked,other.is_locked); 613 } 614 mutex() const615 Mutex* mutex() const BOOST_NOEXCEPT 616 { 617 return m; 618 } 619 release()620 Mutex* release() BOOST_NOEXCEPT 621 { 622 Mutex* const res=m; 623 m=0; 624 is_locked=false; 625 return res; 626 } 627 ~shared_lock()628 ~shared_lock() 629 { 630 if(owns_lock()) 631 { 632 m->unlock_shared(); 633 } 634 } lock()635 void lock() 636 { 637 if(m==0) 638 { 639 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex")); 640 } 641 if(owns_lock()) 642 { 643 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex")); 644 } 645 m->lock_shared(); 646 is_locked=true; 647 } try_lock()648 bool try_lock() 649 { 650 if(m==0) 651 { 652 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex")); 653 } 654 if(owns_lock()) 655 { 656 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex")); 657 } 658 is_locked=m->try_lock_shared(); 659 return is_locked; 660 } 661 #if defined BOOST_THREAD_USES_DATETIME timed_lock(boost::system_time const & target_time)662 bool timed_lock(boost::system_time const& target_time) 663 { 664 if(m==0) 665 { 666 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex")); 667 } 668 if(owns_lock()) 669 { 670 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex")); 671 } 672 is_locked=m->timed_lock_shared(target_time); 673 return is_locked; 674 } 675 template<typename Duration> timed_lock(Duration const & target_time)676 bool timed_lock(Duration const& target_time) 677 { 678 if(m==0) 679 { 680 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex")); 681 } 682 if(owns_lock()) 683 { 684 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex")); 685 } 686 is_locked=m->timed_lock_shared(target_time); 687 return is_locked; 688 } 689 #endif 690 #ifdef BOOST_THREAD_USES_CHRONO 691 template <class Rep, class Period> try_lock_for(const chrono::duration<Rep,Period> & rel_time)692 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) 693 { 694 if(m==0) 695 { 696 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex")); 697 } 698 if(owns_lock()) 699 { 700 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex")); 701 } 702 is_locked=m->try_lock_shared_for(rel_time); 703 return is_locked; 704 } 705 template <class Clock, class Duration> try_lock_until(const chrono::time_point<Clock,Duration> & abs_time)706 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) 707 { 708 if(m==0) 709 { 710 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex")); 711 } 712 if(owns_lock()) 713 { 714 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex")); 715 } 716 is_locked=m->try_lock_shared_until(abs_time); 717 return is_locked; 718 } 719 #endif unlock()720 void unlock() 721 { 722 if(m==0) 723 { 724 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex")); 725 } 726 if(!owns_lock()) 727 { 728 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock doesn't own the mutex")); 729 } 730 m->unlock_shared(); 731 is_locked=false; 732 } 733 734 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) 735 typedef void (shared_lock<Mutex>::*bool_type)(); operator bool_type() const736 operator bool_type() const BOOST_NOEXCEPT 737 { 738 return is_locked?&shared_lock::lock:0; 739 } operator !() const740 bool operator!() const BOOST_NOEXCEPT 741 { 742 return !owns_lock(); 743 } 744 #else operator bool() const745 explicit operator bool() const BOOST_NOEXCEPT 746 { 747 return owns_lock(); 748 } 749 #endif owns_lock() const750 bool owns_lock() const BOOST_NOEXCEPT 751 { 752 return is_locked; 753 } 754 755 }; 756 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex)757 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END 758 759 template<typename Mutex> 760 void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT 761 { 762 lhs.swap(rhs); 763 } 764 765 template <typename Mutex> 766 class upgrade_lock 767 { 768 protected: 769 Mutex* m; 770 bool is_locked; 771 772 public: 773 typedef Mutex mutex_type; 774 BOOST_THREAD_MOVABLE_ONLY( upgrade_lock) 775 upgrade_lock()776 upgrade_lock()BOOST_NOEXCEPT: 777 m(0),is_locked(false) 778 {} 779 upgrade_lock(Mutex & m_)780 explicit upgrade_lock(Mutex& m_) : 781 m(&m_), is_locked(false) 782 { 783 lock(); 784 } upgrade_lock(Mutex & m_,adopt_lock_t)785 upgrade_lock(Mutex& m_, adopt_lock_t) : 786 m(&m_), is_locked(true) 787 { 788 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS 789 BOOST_ASSERT(is_locked_by_this_thread(m)); 790 #endif 791 } upgrade_lock(Mutex & m_,defer_lock_t)792 upgrade_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT: 793 m(&m_),is_locked(false) 794 {} upgrade_lock(Mutex & m_,try_to_lock_t)795 upgrade_lock(Mutex& m_, try_to_lock_t) : 796 m(&m_), is_locked(false) 797 { 798 try_lock(); 799 } 800 801 #ifdef BOOST_THREAD_USES_CHRONO 802 template <class Clock, class Duration> upgrade_lock(Mutex & mtx,const chrono::time_point<Clock,Duration> & t)803 upgrade_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t) 804 : m(&mtx), is_locked(mtx.try_lock_upgrade_until(t)) 805 { 806 } 807 template <class Rep, class Period> upgrade_lock(Mutex & mtx,const chrono::duration<Rep,Period> & d)808 upgrade_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d) 809 : m(&mtx), is_locked(mtx.try_lock_upgrade_for(d)) 810 { 811 } 812 #endif 813 upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)814 upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT: 815 m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) 816 { 817 BOOST_THREAD_RV(other).is_locked=false; 818 BOOST_THREAD_RV(other).m=0; 819 } 820 upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)821 BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other): 822 m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) 823 { 824 if(is_locked) 825 { 826 m->unlock_and_lock_upgrade(); 827 } 828 BOOST_THREAD_RV(other).is_locked=false; 829 BOOST_THREAD_RV(other).m=0; 830 } 831 832 //std-2104 unique_lock move-assignment should not be noexcept operator =(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)833 upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT 834 { 835 upgrade_lock temp(::boost::move(other)); 836 swap(temp); 837 return *this; 838 } 839 840 #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION operator =(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)841 upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) 842 { 843 upgrade_lock temp(::boost::move(other)); 844 swap(temp); 845 return *this; 846 } 847 #endif 848 849 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS 850 // Conversion from shared locking upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,try_to_lock_t)851 upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t) 852 : m(0),is_locked(false) 853 { 854 if (BOOST_THREAD_RV(sl).owns_lock()) 855 { 856 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade()) 857 { 858 m = BOOST_THREAD_RV(sl).release(); 859 is_locked = true; 860 } 861 } 862 else 863 { 864 m = BOOST_THREAD_RV(sl).release(); 865 } 866 } 867 868 #ifdef BOOST_THREAD_USES_CHRONO 869 template <class Clock, class Duration> upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,const chrono::time_point<Clock,Duration> & abs_time)870 upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, 871 const chrono::time_point<Clock, Duration>& abs_time) 872 : m(0),is_locked(false) 873 { 874 if (BOOST_THREAD_RV(sl).owns_lock()) 875 { 876 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time)) 877 { 878 m = BOOST_THREAD_RV(sl).release(); 879 is_locked = true; 880 } 881 } 882 else 883 { 884 m = BOOST_THREAD_RV(sl).release(); 885 } 886 } 887 888 template <class Rep, class Period> upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,const chrono::duration<Rep,Period> & rel_time)889 upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, 890 const chrono::duration<Rep, Period>& rel_time) 891 : m(0),is_locked(false) 892 { 893 if (BOOST_THREAD_RV(sl).owns_lock()) 894 { 895 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time)) 896 { 897 m = BOOST_THREAD_RV(sl).release(); 898 is_locked = true; 899 } 900 } 901 else 902 { 903 m = BOOST_THREAD_RV(sl).release(); 904 } 905 } 906 #endif // BOOST_THREAD_USES_CHRONO 907 #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS swap(upgrade_lock & other)908 void swap(upgrade_lock& other)BOOST_NOEXCEPT 909 { 910 std::swap(m,other.m); 911 std::swap(is_locked,other.is_locked); 912 } mutex() const913 Mutex* mutex() const BOOST_NOEXCEPT 914 { 915 return m; 916 } 917 release()918 Mutex* release()BOOST_NOEXCEPT 919 { 920 Mutex* const res=m; 921 m=0; 922 is_locked=false; 923 return res; 924 } ~upgrade_lock()925 ~upgrade_lock() 926 { 927 if (owns_lock()) 928 { 929 m->unlock_upgrade(); 930 } 931 } lock()932 void lock() 933 { 934 if (m == 0) 935 { 936 boost::throw_exception( 937 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex")); 938 } 939 if (owns_lock()) 940 { 941 boost::throw_exception( 942 boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex")); 943 } 944 m->lock_upgrade(); 945 is_locked = true; 946 } try_lock()947 bool try_lock() 948 { 949 if (m == 0) 950 { 951 boost::throw_exception( 952 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex")); 953 } 954 if (owns_lock()) 955 { 956 boost::throw_exception( 957 boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex")); 958 } 959 is_locked = m->try_lock_upgrade(); 960 return is_locked; 961 } unlock()962 void unlock() 963 { 964 if (m == 0) 965 { 966 boost::throw_exception( 967 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex")); 968 } 969 if (!owns_lock()) 970 { 971 boost::throw_exception( 972 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock doesn't own the mutex")); 973 } 974 m->unlock_upgrade(); 975 is_locked = false; 976 } 977 #ifdef BOOST_THREAD_USES_CHRONO 978 template <class Rep, class Period> try_lock_for(const chrono::duration<Rep,Period> & rel_time)979 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) 980 { 981 if(m==0) 982 { 983 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex")); 984 } 985 if(owns_lock()) 986 { 987 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex")); 988 } 989 is_locked=m->try_lock_upgrade_for(rel_time); 990 return is_locked; 991 } 992 template <class Clock, class Duration> try_lock_until(const chrono::time_point<Clock,Duration> & abs_time)993 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) 994 { 995 if(m==0) 996 { 997 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex")); 998 } 999 if(owns_lock()) 1000 { 1001 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex")); 1002 } 1003 is_locked=m->try_lock_upgrade_until(abs_time); 1004 return is_locked; 1005 } 1006 #endif 1007 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) 1008 typedef void (upgrade_lock::*bool_type)(); operator bool_type() const1009 operator bool_type() const BOOST_NOEXCEPT 1010 { 1011 return is_locked?&upgrade_lock::lock:0; 1012 } operator !() const1013 bool operator!() const BOOST_NOEXCEPT 1014 { 1015 return !owns_lock(); 1016 } 1017 #else operator bool() const1018 explicit operator bool() const BOOST_NOEXCEPT 1019 { 1020 return owns_lock(); 1021 } 1022 #endif owns_lock() const1023 bool owns_lock() const BOOST_NOEXCEPT 1024 { 1025 return is_locked; 1026 } 1027 friend class shared_lock<Mutex> ; 1028 friend class unique_lock<Mutex> ; 1029 }; 1030 1031 template<typename Mutex> swap(upgrade_lock<Mutex> & lhs,upgrade_lock<Mutex> & rhs)1032 void swap(upgrade_lock<Mutex>& lhs, upgrade_lock<Mutex>& rhs) 1033 BOOST_NOEXCEPT 1034 { 1035 lhs.swap(rhs); 1036 } 1037 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex)1038 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END 1039 1040 template<typename Mutex> 1041 unique_lock<Mutex>::unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other): 1042 m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) 1043 { 1044 if(is_locked) 1045 { 1046 m->unlock_upgrade_and_lock(); 1047 } 1048 BOOST_THREAD_RV(other).release(); 1049 } 1050 1051 template <class Mutex> 1052 class upgrade_to_unique_lock 1053 { 1054 private: 1055 upgrade_lock<Mutex>* source; 1056 unique_lock<Mutex> exclusive; 1057 1058 public: 1059 typedef Mutex mutex_type; 1060 BOOST_THREAD_MOVABLE_ONLY( upgrade_to_unique_lock) 1061 upgrade_to_unique_lock(upgrade_lock<Mutex> & m_)1062 explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_) : 1063 source(&m_), exclusive(::boost::move(*source)) 1064 { 1065 } ~upgrade_to_unique_lock()1066 ~upgrade_to_unique_lock() 1067 { 1068 if (source) 1069 { 1070 *source = BOOST_THREAD_MAKE_RV_REF(upgrade_lock<Mutex> (::boost::move(exclusive))); 1071 } 1072 } 1073 upgrade_to_unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)1074 upgrade_to_unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT: 1075 source(BOOST_THREAD_RV(other).source),exclusive(::boost::move(BOOST_THREAD_RV(other).exclusive)) 1076 { 1077 BOOST_THREAD_RV(other).source=0; 1078 } 1079 1080 //std-2104 unique_lock move-assignment should not be noexcept operator =(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)1081 upgrade_to_unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT 1082 { 1083 upgrade_to_unique_lock temp(::boost::move(other)); 1084 swap(temp); 1085 return *this; 1086 } 1087 swap(upgrade_to_unique_lock & other)1088 void swap(upgrade_to_unique_lock& other)BOOST_NOEXCEPT 1089 { 1090 std::swap(source,other.source); 1091 exclusive.swap(other.exclusive); 1092 } 1093 1094 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) 1095 typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&); operator bool_type() const1096 operator bool_type() const BOOST_NOEXCEPT 1097 { 1098 return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0; 1099 } operator !() const1100 bool operator!() const BOOST_NOEXCEPT 1101 { 1102 return !owns_lock(); 1103 } 1104 #else operator bool() const1105 explicit operator bool() const BOOST_NOEXCEPT 1106 { 1107 return owns_lock(); 1108 } 1109 #endif 1110 owns_lock() const1111 bool owns_lock() const BOOST_NOEXCEPT 1112 { 1113 return exclusive.owns_lock(); 1114 } mutex() const1115 Mutex* mutex() const BOOST_NOEXCEPT 1116 { 1117 return exclusive.mutex(); 1118 } 1119 }; 1120 1121 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END 1122 1123 namespace detail 1124 { 1125 template<typename Mutex> 1126 class try_lock_wrapper: 1127 private unique_lock<Mutex> 1128 { 1129 typedef unique_lock<Mutex> base; 1130 public: 1131 BOOST_THREAD_MOVABLE_ONLY(try_lock_wrapper) 1132 try_lock_wrapper()1133 try_lock_wrapper() 1134 {} 1135 try_lock_wrapper(Mutex & m)1136 explicit try_lock_wrapper(Mutex& m): 1137 base(m,try_to_lock) 1138 {} 1139 try_lock_wrapper(Mutex & m_,adopt_lock_t)1140 try_lock_wrapper(Mutex& m_,adopt_lock_t): 1141 base(m_,adopt_lock) 1142 { 1143 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS 1144 BOOST_ASSERT(is_locked_by_this_thread(m_)); 1145 #endif 1146 } try_lock_wrapper(Mutex & m_,defer_lock_t)1147 try_lock_wrapper(Mutex& m_,defer_lock_t): 1148 base(m_,defer_lock) 1149 {} try_lock_wrapper(Mutex & m_,try_to_lock_t)1150 try_lock_wrapper(Mutex& m_,try_to_lock_t): 1151 base(m_,try_to_lock) 1152 {} 1153 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES try_lock_wrapper(BOOST_THREAD_RV_REF (try_lock_wrapper)other)1154 try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other): 1155 base(::boost::move(other)) 1156 {} 1157 1158 #elif defined BOOST_THREAD_USES_MOVE try_lock_wrapper(BOOST_THREAD_RV_REF (try_lock_wrapper)other)1159 try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other): 1160 base(::boost::move(static_cast<base&>(other))) 1161 {} 1162 1163 #else try_lock_wrapper(BOOST_THREAD_RV_REF (try_lock_wrapper)other)1164 try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other): 1165 base(BOOST_THREAD_RV_REF(base)(*other)) 1166 {} 1167 #endif operator =(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)1168 try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other) 1169 { 1170 try_lock_wrapper temp(::boost::move(other)); 1171 swap(temp); 1172 return *this; 1173 } swap(try_lock_wrapper & other)1174 void swap(try_lock_wrapper& other) 1175 { 1176 base::swap(other); 1177 } lock()1178 void lock() 1179 { 1180 base::lock(); 1181 } try_lock()1182 bool try_lock() 1183 { 1184 return base::try_lock(); 1185 } unlock()1186 void unlock() 1187 { 1188 base::unlock(); 1189 } owns_lock() const1190 bool owns_lock() const 1191 { 1192 return base::owns_lock(); 1193 } mutex() const1194 Mutex* mutex() const BOOST_NOEXCEPT 1195 { 1196 return base::mutex(); 1197 } release()1198 Mutex* release() 1199 { 1200 return base::release(); 1201 } 1202 1203 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) 1204 typedef typename base::bool_type bool_type; operator bool_type() const1205 operator bool_type() const 1206 { 1207 return base::operator bool_type(); 1208 } operator !() const1209 bool operator!() const 1210 { 1211 return !this->owns_lock(); 1212 } 1213 #else operator bool() const1214 explicit operator bool() const 1215 { 1216 return owns_lock(); 1217 } 1218 #endif 1219 }; 1220 1221 template<typename Mutex> swap(try_lock_wrapper<Mutex> & lhs,try_lock_wrapper<Mutex> & rhs)1222 void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs) 1223 { 1224 lhs.swap(rhs); 1225 } 1226 } 1227 } 1228 #include <boost/config/abi_suffix.hpp> 1229 1230 #endif 1231