annotate DEPENDENCIES/generic/include/boost/thread/pthread/shared_mutex.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 #ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
Chris@16 2 #define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
Chris@16 3
Chris@16 4 // (C) Copyright 2006-8 Anthony Williams
Chris@16 5 // (C) Copyright 2012 Vicente J. Botet Escriba
Chris@16 6 //
Chris@16 7 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 8 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 9 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10
Chris@16 11 #include <boost/assert.hpp>
Chris@16 12 #include <boost/static_assert.hpp>
Chris@16 13 #include <boost/thread/mutex.hpp>
Chris@16 14 #include <boost/thread/condition_variable.hpp>
Chris@16 15 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 16 #include <boost/thread/detail/thread_interruption.hpp>
Chris@16 17 #endif
Chris@16 18 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 19 #include <boost/chrono/system_clocks.hpp>
Chris@16 20 #include <boost/chrono/ceil.hpp>
Chris@16 21 #endif
Chris@16 22 #include <boost/thread/detail/delete.hpp>
Chris@16 23 #include <boost/assert.hpp>
Chris@16 24
Chris@16 25 #include <boost/config/abi_prefix.hpp>
Chris@16 26
Chris@16 27 namespace boost
Chris@16 28 {
Chris@16 29 class shared_mutex
Chris@16 30 {
Chris@16 31 private:
Chris@16 32 class state_data
Chris@16 33 {
Chris@16 34 public:
Chris@16 35 state_data () :
Chris@16 36 shared_count(0),
Chris@16 37 exclusive(false),
Chris@16 38 upgrade(false),
Chris@16 39 exclusive_waiting_blocked(false)
Chris@16 40 {}
Chris@16 41
Chris@16 42 void assert_free() const
Chris@16 43 {
Chris@16 44 BOOST_ASSERT( ! exclusive );
Chris@16 45 BOOST_ASSERT( ! upgrade );
Chris@16 46 BOOST_ASSERT( shared_count==0 );
Chris@16 47 }
Chris@16 48
Chris@16 49 void assert_locked() const
Chris@16 50 {
Chris@16 51 BOOST_ASSERT( exclusive );
Chris@16 52 BOOST_ASSERT( shared_count==0 );
Chris@16 53 BOOST_ASSERT( ! upgrade );
Chris@16 54 }
Chris@16 55
Chris@16 56 void assert_lock_shared () const
Chris@16 57 {
Chris@16 58 BOOST_ASSERT( ! exclusive );
Chris@16 59 BOOST_ASSERT( shared_count>0 );
Chris@16 60 //BOOST_ASSERT( (! upgrade) || (shared_count>1));
Chris@16 61 // if upgraded there are at least 2 threads sharing the mutex,
Chris@16 62 // except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.
Chris@16 63 }
Chris@16 64
Chris@16 65 void assert_lock_upgraded () const
Chris@16 66 {
Chris@16 67 BOOST_ASSERT( ! exclusive );
Chris@16 68 BOOST_ASSERT( upgrade );
Chris@16 69 BOOST_ASSERT( shared_count>0 );
Chris@16 70 }
Chris@16 71
Chris@16 72 void assert_lock_not_upgraded () const
Chris@16 73 {
Chris@16 74 BOOST_ASSERT( ! upgrade );
Chris@16 75 }
Chris@16 76
Chris@16 77 bool can_lock () const
Chris@16 78 {
Chris@16 79 return ! (shared_count || exclusive);
Chris@16 80 }
Chris@16 81
Chris@16 82 void exclusive_blocked (bool blocked)
Chris@16 83 {
Chris@16 84 exclusive_waiting_blocked = blocked;
Chris@16 85 }
Chris@16 86
Chris@16 87 void lock ()
Chris@16 88 {
Chris@16 89 exclusive = true;
Chris@16 90 }
Chris@16 91
Chris@16 92 void unlock ()
Chris@16 93 {
Chris@16 94 exclusive = false;
Chris@16 95 exclusive_waiting_blocked = false;
Chris@16 96 }
Chris@16 97
Chris@16 98 bool can_lock_shared () const
Chris@16 99 {
Chris@16 100 return ! (exclusive || exclusive_waiting_blocked);
Chris@16 101 }
Chris@16 102
Chris@16 103 bool more_shared () const
Chris@16 104 {
Chris@16 105 return shared_count > 0 ;
Chris@16 106 }
Chris@16 107 unsigned get_shared_count () const
Chris@16 108 {
Chris@16 109 return shared_count ;
Chris@16 110 }
Chris@16 111 unsigned lock_shared ()
Chris@16 112 {
Chris@16 113 return ++shared_count;
Chris@16 114 }
Chris@16 115
Chris@16 116
Chris@16 117 void unlock_shared ()
Chris@16 118 {
Chris@16 119 --shared_count;
Chris@16 120 }
Chris@16 121
Chris@16 122 bool unlock_shared_downgrades()
Chris@16 123 {
Chris@16 124 if (upgrade) {
Chris@16 125 upgrade=false;
Chris@16 126 exclusive=true;
Chris@16 127 return true;
Chris@16 128 } else {
Chris@16 129 exclusive_waiting_blocked=false;
Chris@16 130 return false;
Chris@16 131 }
Chris@16 132 }
Chris@16 133
Chris@16 134 void lock_upgrade ()
Chris@16 135 {
Chris@16 136 ++shared_count;
Chris@16 137 upgrade=true;
Chris@16 138 }
Chris@16 139 bool can_lock_upgrade () const
Chris@16 140 {
Chris@16 141 return ! (exclusive || exclusive_waiting_blocked || upgrade);
Chris@16 142 }
Chris@16 143
Chris@16 144 void unlock_upgrade ()
Chris@16 145 {
Chris@16 146 upgrade=false;
Chris@16 147 --shared_count;
Chris@16 148 }
Chris@16 149
Chris@16 150 //private:
Chris@16 151 unsigned shared_count;
Chris@16 152 bool exclusive;
Chris@16 153 bool upgrade;
Chris@16 154 bool exclusive_waiting_blocked;
Chris@16 155 };
Chris@16 156
Chris@16 157
Chris@16 158
Chris@16 159 state_data state;
Chris@16 160 boost::mutex state_change;
Chris@16 161 boost::condition_variable shared_cond;
Chris@16 162 boost::condition_variable exclusive_cond;
Chris@16 163 boost::condition_variable upgrade_cond;
Chris@16 164
Chris@16 165 void release_waiters()
Chris@16 166 {
Chris@16 167 exclusive_cond.notify_one();
Chris@16 168 shared_cond.notify_all();
Chris@16 169 }
Chris@16 170
Chris@16 171 public:
Chris@16 172
Chris@16 173 BOOST_THREAD_NO_COPYABLE(shared_mutex)
Chris@16 174
Chris@16 175 shared_mutex()
Chris@16 176 {
Chris@16 177 }
Chris@16 178
Chris@16 179 ~shared_mutex()
Chris@16 180 {
Chris@16 181 }
Chris@16 182
Chris@16 183 void lock_shared()
Chris@16 184 {
Chris@16 185 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 186 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 187 #endif
Chris@16 188 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 189 while(!state.can_lock_shared())
Chris@16 190 {
Chris@16 191 shared_cond.wait(lk);
Chris@16 192 }
Chris@16 193 state.lock_shared();
Chris@16 194 }
Chris@16 195
Chris@16 196 bool try_lock_shared()
Chris@16 197 {
Chris@16 198 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 199
Chris@16 200 if(!state.can_lock_shared())
Chris@16 201 {
Chris@16 202 return false;
Chris@16 203 }
Chris@16 204 state.lock_shared();
Chris@16 205 return true;
Chris@16 206 }
Chris@16 207
Chris@16 208 #if defined BOOST_THREAD_USES_DATETIME
Chris@16 209 bool timed_lock_shared(system_time const& timeout)
Chris@16 210 {
Chris@16 211 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 212 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 213 #endif
Chris@16 214 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 215
Chris@16 216 while(!state.can_lock_shared())
Chris@16 217 {
Chris@16 218 if(!shared_cond.timed_wait(lk,timeout))
Chris@16 219 {
Chris@16 220 return false;
Chris@16 221 }
Chris@16 222 }
Chris@16 223 state.lock_shared();
Chris@16 224 return true;
Chris@16 225 }
Chris@16 226
Chris@16 227 template<typename TimeDuration>
Chris@16 228 bool timed_lock_shared(TimeDuration const & relative_time)
Chris@16 229 {
Chris@16 230 return timed_lock_shared(get_system_time()+relative_time);
Chris@16 231 }
Chris@16 232 #endif
Chris@16 233 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 234 template <class Rep, class Period>
Chris@16 235 bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
Chris@16 236 {
Chris@16 237 return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
Chris@16 238 }
Chris@16 239 template <class Clock, class Duration>
Chris@16 240 bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
Chris@16 241 {
Chris@16 242 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 243 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 244 #endif
Chris@16 245 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 246
Chris@16 247 while(!state.can_lock_shared())
Chris@16 248 //while(state.exclusive || state.exclusive_waiting_blocked)
Chris@16 249 {
Chris@16 250 if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
Chris@16 251 {
Chris@16 252 return false;
Chris@16 253 }
Chris@16 254 }
Chris@16 255 state.lock_shared();
Chris@16 256 return true;
Chris@16 257 }
Chris@16 258 #endif
Chris@16 259 void unlock_shared()
Chris@16 260 {
Chris@16 261 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 262 state.assert_lock_shared();
Chris@16 263 state.unlock_shared();
Chris@16 264 if (! state.more_shared())
Chris@16 265 {
Chris@16 266 if (state.upgrade)
Chris@16 267 {
Chris@16 268 // As there is a thread doing a unlock_upgrade_and_lock that is waiting for ! state.more_shared()
Chris@16 269 // avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
Chris@16 270 state.upgrade=false;
Chris@16 271 state.exclusive=true;
Chris@16 272 lk.unlock();
Chris@16 273 upgrade_cond.notify_one();
Chris@16 274 }
Chris@16 275 else
Chris@16 276 {
Chris@16 277 state.exclusive_waiting_blocked=false;
Chris@16 278 lk.unlock();
Chris@16 279 }
Chris@16 280 release_waiters();
Chris@16 281 }
Chris@16 282 }
Chris@16 283
Chris@16 284 void lock()
Chris@16 285 {
Chris@16 286 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 287 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 288 #endif
Chris@16 289 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 290
Chris@16 291 while (state.shared_count || state.exclusive)
Chris@16 292 {
Chris@16 293 state.exclusive_waiting_blocked=true;
Chris@16 294 exclusive_cond.wait(lk);
Chris@16 295 }
Chris@16 296 state.exclusive=true;
Chris@16 297 }
Chris@16 298
Chris@16 299 #if defined BOOST_THREAD_USES_DATETIME
Chris@16 300 bool timed_lock(system_time const& timeout)
Chris@16 301 {
Chris@16 302 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 303 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 304 #endif
Chris@16 305 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 306
Chris@16 307 while(state.shared_count || state.exclusive)
Chris@16 308 {
Chris@16 309 state.exclusive_waiting_blocked=true;
Chris@16 310 if(!exclusive_cond.timed_wait(lk,timeout))
Chris@16 311 {
Chris@16 312 if(state.shared_count || state.exclusive)
Chris@16 313 {
Chris@16 314 state.exclusive_waiting_blocked=false;
Chris@16 315 release_waiters();
Chris@16 316 return false;
Chris@16 317 }
Chris@16 318 break;
Chris@16 319 }
Chris@16 320 }
Chris@16 321 state.exclusive=true;
Chris@16 322 return true;
Chris@16 323 }
Chris@16 324
Chris@16 325 template<typename TimeDuration>
Chris@16 326 bool timed_lock(TimeDuration const & relative_time)
Chris@16 327 {
Chris@16 328 return timed_lock(get_system_time()+relative_time);
Chris@16 329 }
Chris@16 330 #endif
Chris@16 331 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 332 template <class Rep, class Period>
Chris@16 333 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
Chris@16 334 {
Chris@16 335 return try_lock_until(chrono::steady_clock::now() + rel_time);
Chris@16 336 }
Chris@16 337 template <class Clock, class Duration>
Chris@16 338 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
Chris@16 339 {
Chris@16 340 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 341 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 342 #endif
Chris@16 343 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 344
Chris@16 345 while(state.shared_count || state.exclusive)
Chris@16 346 {
Chris@16 347 state.exclusive_waiting_blocked=true;
Chris@16 348 if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
Chris@16 349 {
Chris@16 350 if(state.shared_count || state.exclusive)
Chris@16 351 {
Chris@16 352 state.exclusive_waiting_blocked=false;
Chris@16 353 release_waiters();
Chris@16 354 return false;
Chris@16 355 }
Chris@16 356 break;
Chris@16 357 }
Chris@16 358 }
Chris@16 359 state.exclusive=true;
Chris@16 360 return true;
Chris@16 361 }
Chris@16 362 #endif
Chris@16 363
Chris@16 364 bool try_lock()
Chris@16 365 {
Chris@16 366 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 367
Chris@16 368 if(state.shared_count || state.exclusive)
Chris@16 369 {
Chris@16 370 return false;
Chris@16 371 }
Chris@16 372 else
Chris@16 373 {
Chris@16 374 state.exclusive=true;
Chris@16 375 return true;
Chris@16 376 }
Chris@16 377
Chris@16 378 }
Chris@16 379
Chris@16 380 void unlock()
Chris@16 381 {
Chris@16 382 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 383 state.assert_locked();
Chris@16 384 state.exclusive=false;
Chris@16 385 state.exclusive_waiting_blocked=false;
Chris@16 386 state.assert_free();
Chris@16 387 release_waiters();
Chris@16 388 }
Chris@16 389
Chris@16 390 void lock_upgrade()
Chris@16 391 {
Chris@16 392 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 393 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 394 #endif
Chris@16 395 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 396 while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
Chris@16 397 {
Chris@16 398 shared_cond.wait(lk);
Chris@16 399 }
Chris@16 400 state.lock_shared();
Chris@16 401 state.upgrade=true;
Chris@16 402 }
Chris@16 403
Chris@16 404 #if defined BOOST_THREAD_USES_DATETIME
Chris@16 405 bool timed_lock_upgrade(system_time const& timeout)
Chris@16 406 {
Chris@16 407 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 408 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 409 #endif
Chris@16 410 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 411 while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
Chris@16 412 {
Chris@16 413 if(!shared_cond.timed_wait(lk,timeout))
Chris@16 414 {
Chris@16 415 if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
Chris@16 416 {
Chris@16 417 return false;
Chris@16 418 }
Chris@16 419 break;
Chris@16 420 }
Chris@16 421 }
Chris@16 422 state.lock_shared();
Chris@16 423 state.upgrade=true;
Chris@16 424 return true;
Chris@16 425 }
Chris@16 426
Chris@16 427 template<typename TimeDuration>
Chris@16 428 bool timed_lock_upgrade(TimeDuration const & relative_time)
Chris@16 429 {
Chris@16 430 return timed_lock_upgrade(get_system_time()+relative_time);
Chris@16 431 }
Chris@16 432 #endif
Chris@16 433 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 434 template <class Rep, class Period>
Chris@16 435 bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
Chris@16 436 {
Chris@16 437 return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
Chris@16 438 }
Chris@16 439 template <class Clock, class Duration>
Chris@16 440 bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
Chris@16 441 {
Chris@16 442 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 443 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 444 #endif
Chris@16 445 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 446 while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
Chris@16 447 {
Chris@16 448 if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
Chris@16 449 {
Chris@16 450 if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
Chris@16 451 {
Chris@16 452 return false;
Chris@16 453 }
Chris@16 454 break;
Chris@16 455 }
Chris@16 456 }
Chris@16 457 state.lock_shared();
Chris@16 458 state.upgrade=true;
Chris@16 459 return true;
Chris@16 460 }
Chris@16 461 #endif
Chris@16 462 bool try_lock_upgrade()
Chris@16 463 {
Chris@16 464 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 465 if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
Chris@16 466 {
Chris@16 467 return false;
Chris@16 468 }
Chris@16 469 else
Chris@16 470 {
Chris@16 471 state.lock_shared();
Chris@16 472 state.upgrade=true;
Chris@16 473 state.assert_lock_upgraded();
Chris@16 474 return true;
Chris@16 475 }
Chris@16 476 }
Chris@16 477
Chris@16 478 void unlock_upgrade()
Chris@16 479 {
Chris@16 480 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 481 //state.upgrade=false;
Chris@16 482 state.unlock_upgrade();
Chris@16 483 if(! state.more_shared() )
Chris@16 484 {
Chris@16 485 state.exclusive_waiting_blocked=false;
Chris@16 486 release_waiters();
Chris@16 487 } else {
Chris@16 488 shared_cond.notify_all();
Chris@16 489 }
Chris@16 490 }
Chris@16 491
Chris@16 492 // Upgrade <-> Exclusive
Chris@16 493 void unlock_upgrade_and_lock()
Chris@16 494 {
Chris@16 495 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 496 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 497 #endif
Chris@16 498 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 499 state.assert_lock_upgraded();
Chris@16 500 state.unlock_shared();
Chris@16 501 while (state.more_shared())
Chris@16 502 {
Chris@16 503 upgrade_cond.wait(lk);
Chris@16 504 }
Chris@16 505 state.upgrade=false;
Chris@16 506 state.exclusive=true;
Chris@16 507 state.assert_locked();
Chris@16 508 }
Chris@16 509
Chris@16 510 void unlock_and_lock_upgrade()
Chris@16 511 {
Chris@16 512 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 513 state.assert_locked();
Chris@16 514 state.exclusive=false;
Chris@16 515 state.upgrade=true;
Chris@16 516 state.lock_shared();
Chris@16 517 state.exclusive_waiting_blocked=false;
Chris@16 518 state.assert_lock_upgraded();
Chris@16 519 release_waiters();
Chris@16 520 }
Chris@16 521
Chris@16 522 bool try_unlock_upgrade_and_lock()
Chris@16 523 {
Chris@16 524 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 525 state.assert_lock_upgraded();
Chris@16 526 if( !state.exclusive
Chris@16 527 && !state.exclusive_waiting_blocked
Chris@16 528 && state.upgrade
Chris@16 529 && state.shared_count==1)
Chris@16 530 {
Chris@16 531 state.shared_count=0;
Chris@16 532 state.exclusive=true;
Chris@16 533 state.upgrade=false;
Chris@16 534 state.assert_locked();
Chris@16 535 return true;
Chris@16 536 }
Chris@16 537 return false;
Chris@16 538 }
Chris@16 539 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 540 template <class Rep, class Period>
Chris@16 541 bool
Chris@16 542 try_unlock_upgrade_and_lock_for(
Chris@16 543 const chrono::duration<Rep, Period>& rel_time)
Chris@16 544 {
Chris@16 545 return try_unlock_upgrade_and_lock_until(
Chris@16 546 chrono::steady_clock::now() + rel_time);
Chris@16 547 }
Chris@16 548 template <class Clock, class Duration>
Chris@16 549 bool
Chris@16 550 try_unlock_upgrade_and_lock_until(
Chris@16 551 const chrono::time_point<Clock, Duration>& abs_time)
Chris@16 552 {
Chris@16 553 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 554 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 555 #endif
Chris@16 556 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 557 state.assert_lock_upgraded();
Chris@16 558 if (state.shared_count != 1)
Chris@16 559 {
Chris@16 560 for (;;)
Chris@16 561 {
Chris@16 562 cv_status status = shared_cond.wait_until(lk,abs_time);
Chris@16 563 if (state.shared_count == 1)
Chris@16 564 break;
Chris@16 565 if(status == cv_status::timeout)
Chris@16 566 return false;
Chris@16 567 }
Chris@16 568 }
Chris@16 569 state.upgrade=false;
Chris@16 570 state.exclusive=true;
Chris@16 571 state.exclusive_waiting_blocked=false;
Chris@16 572 state.shared_count=0;
Chris@16 573 return true;
Chris@16 574 }
Chris@16 575 #endif
Chris@16 576
Chris@16 577 // Shared <-> Exclusive
Chris@16 578 void unlock_and_lock_shared()
Chris@16 579 {
Chris@16 580 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 581 state.assert_locked();
Chris@16 582 state.exclusive=false;
Chris@16 583 state.lock_shared();
Chris@16 584 state.exclusive_waiting_blocked=false;
Chris@16 585 release_waiters();
Chris@16 586 }
Chris@16 587
Chris@16 588 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
Chris@16 589 bool try_unlock_shared_and_lock()
Chris@16 590 {
Chris@16 591 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 592 state.assert_lock_shared();
Chris@16 593 if( !state.exclusive
Chris@16 594 && !state.exclusive_waiting_blocked
Chris@16 595 && !state.upgrade
Chris@16 596 && state.shared_count==1)
Chris@16 597 {
Chris@16 598 state.shared_count=0;
Chris@16 599 state.exclusive=true;
Chris@16 600 return true;
Chris@16 601 }
Chris@16 602 return false;
Chris@16 603 }
Chris@16 604 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 605 template <class Rep, class Period>
Chris@16 606 bool
Chris@16 607 try_unlock_shared_and_lock_for(
Chris@16 608 const chrono::duration<Rep, Period>& rel_time)
Chris@16 609 {
Chris@16 610 return try_unlock_shared_and_lock_until(
Chris@16 611 chrono::steady_clock::now() + rel_time);
Chris@16 612 }
Chris@16 613 template <class Clock, class Duration>
Chris@16 614 bool
Chris@16 615 try_unlock_shared_and_lock_until(
Chris@16 616 const chrono::time_point<Clock, Duration>& abs_time)
Chris@16 617 {
Chris@16 618 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 619 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 620 #endif
Chris@16 621 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 622 state.assert_lock_shared();
Chris@16 623 if (state.shared_count != 1)
Chris@16 624 {
Chris@16 625 for (;;)
Chris@16 626 {
Chris@16 627 cv_status status = shared_cond.wait_until(lk,abs_time);
Chris@16 628 if (state.shared_count == 1)
Chris@16 629 break;
Chris@16 630 if(status == cv_status::timeout)
Chris@16 631 return false;
Chris@16 632 }
Chris@16 633 }
Chris@16 634 state.upgrade=false;
Chris@16 635 state.exclusive=true;
Chris@16 636 state.exclusive_waiting_blocked=false;
Chris@16 637 state.shared_count=0;
Chris@16 638 return true;
Chris@16 639 }
Chris@16 640 #endif
Chris@16 641 #endif
Chris@16 642
Chris@16 643 // Shared <-> Upgrade
Chris@16 644 void unlock_upgrade_and_lock_shared()
Chris@16 645 {
Chris@16 646 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 647 state.assert_lock_upgraded();
Chris@16 648 state.upgrade=false;
Chris@16 649 state.exclusive_waiting_blocked=false;
Chris@16 650 release_waiters();
Chris@16 651 }
Chris@16 652
Chris@16 653 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
Chris@16 654 bool try_unlock_shared_and_lock_upgrade()
Chris@16 655 {
Chris@16 656 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 657 state.assert_lock_shared();
Chris@16 658 if( !state.exclusive
Chris@16 659 && !state.exclusive_waiting_blocked
Chris@16 660 && !state.upgrade
Chris@16 661 )
Chris@16 662 {
Chris@16 663 state.upgrade=true;
Chris@16 664 return true;
Chris@16 665 }
Chris@16 666 return false;
Chris@16 667 }
Chris@16 668 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 669 template <class Rep, class Period>
Chris@16 670 bool
Chris@16 671 try_unlock_shared_and_lock_upgrade_for(
Chris@16 672 const chrono::duration<Rep, Period>& rel_time)
Chris@16 673 {
Chris@16 674 return try_unlock_shared_and_lock_upgrade_until(
Chris@16 675 chrono::steady_clock::now() + rel_time);
Chris@16 676 }
Chris@16 677 template <class Clock, class Duration>
Chris@16 678 bool
Chris@16 679 try_unlock_shared_and_lock_upgrade_until(
Chris@16 680 const chrono::time_point<Clock, Duration>& abs_time)
Chris@16 681 {
Chris@16 682 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 683 boost::this_thread::disable_interruption do_not_disturb;
Chris@16 684 #endif
Chris@16 685 boost::unique_lock<boost::mutex> lk(state_change);
Chris@16 686 state.assert_lock_shared();
Chris@16 687 if( state.exclusive
Chris@16 688 || state.exclusive_waiting_blocked
Chris@16 689 || state.upgrade
Chris@16 690 )
Chris@16 691 {
Chris@16 692 for (;;)
Chris@16 693 {
Chris@16 694 cv_status status = exclusive_cond.wait_until(lk,abs_time);
Chris@16 695 if( ! state.exclusive
Chris@16 696 && ! state.exclusive_waiting_blocked
Chris@16 697 && ! state.upgrade
Chris@16 698 )
Chris@16 699 break;
Chris@16 700 if(status == cv_status::timeout)
Chris@16 701 return false;
Chris@16 702 }
Chris@16 703 }
Chris@16 704 state.upgrade=true;
Chris@16 705 return true;
Chris@16 706 }
Chris@16 707 #endif
Chris@16 708 #endif
Chris@16 709 };
Chris@16 710
Chris@16 711 typedef shared_mutex upgrade_mutex;
Chris@16 712 }
Chris@16 713
Chris@16 714 #include <boost/config/abi_suffix.hpp>
Chris@16 715
Chris@16 716 #endif