2 (C) Copyright 2007-8 Anthony Williams.
3 (C) Copyright 2011-12 Vicente J. Botet Escriba.
4 Distributed under the Boost Software License, Version 1.0.
5 (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
9 [section:mutex_concepts Mutex Concepts]
11 A mutex object facilitates protection against data races and allows thread-safe synchronization of data between threads. A thread
12 obtains ownership of a mutex object by calling one of the lock functions and relinquishes ownership by calling the corresponding
13 unlock function. Mutexes may be either recursive or non-recursive, and may grant simultaneous ownership to one or many
14 threads. __boost_thread__ supplies recursive and non-recursive mutexes with exclusive ownership semantics, along with a shared
15 ownership (multiple-reader / single-writer) mutex.
17 __boost_thread__ supports four basic concepts for lockable objects: __lockable_concept_type__, __timed_lockable_concept_type__,
18 __shared_lockable_concept_type__ and __upgrade_lockable_concept_type__. Each mutex type implements one or more of these concepts, as
19 do the various lock types.
21 [section:basic_lockable `BasicLockable` Concept]
23 // #include <boost/thread/lockable_concepts.hpp>
29 class BasicLockable; // EXTENSION
33 The __BasicLockable concept models exclusive ownership.
34 A type `L` meets the __BasicLockable requirements if the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`):
39 Lock ownership acquired through a call to __lock_ref__ must be released through a call to __unlock_ref__.
41 [section:lock `m.lock();`]
45 [[Requires:] [The calling thread doesn't owns the mutex if the mutex is not recursive.]]
47 [[Effects:] [The current thread blocks until ownership can be obtained for the current thread.]]
49 [[Synchronization:] [Prior `unlock()` operations on the same object synchronizes with this operation. ]]
51 [[Postcondition:] [The current thread owns `m`.]]
53 [[Return type:] [`void`.]]
55 [[Throws:] [__lock_error__ if an error occurs.]]
57 [[Error Conditions:] [
59 [*operation_not_permitted]: if the thread does not have the privilege to perform the operation.
61 [*resource_deadlock_would_occur]: if the implementation detects that a deadlock would occur.
63 [*device_or_resource_busy]: if the mutex is already locked and blocking is not possible.
67 [[Thread safety:] [If an exception is thrown then a lock shall not have been acquired for the current thread.]]
72 [section:unlock `m.unlock();`]
76 [[Requires:] [The current thread owns `m`.]]
78 [[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership on the same object.]]
80 [[Effects:] [Releases a lock on `m` by the current thread.]]
82 [[Return type:] [`void`.]]
84 [[Throws:] [Nothing.]]
89 [section:is_basic_lockable `is_basic_lockable` trait -- EXTENSION]
91 // #include <boost/thread/lockable_traits.hpp>
98 class is_basic_lockable;// EXTENSION
103 Some of the algorithms on mutexes use this trait via SFINAE.
105 This trait is true_type if the parameter L meets the __Lockable requirements.
107 [warning If BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES is defined you will need to specialize this traits for the models of BasicLockable you could build.]
112 [section:lockable `Lockable` Concept]
114 // #include <boost/thread/lockable_concepts.hpp>
121 A type `L` meets the __Lockable requirements if it meets the __BasicLockable requirements and the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`):
125 Lock ownership acquired through a call to __try_lock_ref__ must be released through a call to __unlock_ref__.
127 [section:try_lock `m.try_lock()`]
132 [[Requires:] [The calling thread doesn't owns the mutex if the mutex is not recursive.]]
134 [[Effects:] [Attempt to obtain ownership for the current thread without blocking.]]
136 [[Synchronization:] [If `try_lock()` returns true, prior `unlock()` operations on the same object synchronize with this operation.]]
138 [[Note:] [Since `lock()` does not synchronize with a failed subsequent
139 `try_lock()`, the visibility rules are weak enough that little would be known about the state after a
140 failure, even in the absence of spurious failures.]]
142 [[Return type:] [`bool`.]]
144 [[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
146 [[Postcondition:] [If the call returns `true`, the current thread owns the `m`.]]
148 [[Throws:] [Nothing.]]
153 [section:is_lockable `is_lockable` trait -- EXTENSION]
155 // #include <boost/thread/lockable_traits.hpp>
161 class is_lockable;// EXTENSION
165 Some of the algorithms on mutexes use this trait via SFINAE.
167 This trait is true_type if the parameter L meets the __Lockable requirements.
169 [warning If BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES is defined you will need to specialize this traits for the models of Lockable you could build.]
174 [section:recursive Recursive Lockable Concept]
176 The user could require that the mutex passed to an algorithm is a recursive one. Whether a lockable is recursive or not can not be checked using template meta-programming. This is the motivation for the following trait.
179 [section:is_recursive_mutex_sur_parole `is_recursive_mutex_sur_parole` trait -- EXTENSION]
181 // #include <boost/thread/lockable_traits.hpp>
188 class is_recursive_mutex_sur_parole: false_type; // EXTENSION
190 class is_recursive_mutex_sur_parole<recursive_mutex>: true_type; // EXTENSION
192 class is_recursive_mutex_sur_parole<timed_recursive_mutex>: true_type; // EXTENSION
196 The trait `is_recursive_mutex_sur_parole` is `false_type` by default and is specialized for the provide `recursive_mutex` and `timed_recursive_mutex`.
198 It should be specialized by the user providing other model of recursive lockable.
202 [section:is_recursive_basic_lockable `is_recursive_basic_lockable` trait -- EXTENSION]
204 // #include <boost/thread/lockable_traits.hpp>
210 class is_recursive_basic_lockable;// EXTENSION
214 This traits is true_type if is_basic_lockable and is_recursive_mutex_sur_parole.
217 [section:is_recursive_lockable `is_recursive_lockable` trait -- EXTENSION]
219 // #include <boost/thread/lockable_traits.hpp>
225 class is_recursive_lockable;// EXTENSION
229 This traits is true_type if is_lockable and is_recursive_mutex_sur_parole.
236 [section:timed_lockable `TimedLockable` Concept]
238 // #include <boost/thread/lockable_concepts.hpp>
243 class TimedLockable; // EXTENSION
246 The __timed_lockable_concept__ refines the __lockable_concept__ to add support for
247 timeouts when trying to acquire the lock.
249 A type `L` meets the __TimedLockable requirements if it meets the __Lockable requirements and the following expressions are well-formed and have the specified semantics.
253 * `m` denotes a value of type `L`,
254 * `rel_time` denotes a value of an instantiation of `chrono::duration`, and
255 * `abs_time` denotes a value of an instantiation of `chrono::time_point`:
259 * `m.__try_lock_for(rel_time)`
260 * `m.__try_lock_until(abs_time)`
262 Lock ownership acquired through a call to __try_lock_for or __try_lock_until must be released through a call to __unlock.
264 [section:try_lock_until `m.try_lock_until(abs_time)`]
268 [[Requires:] [The calling thread doesn't owns the mutex if the mutex is not recursive.]]
270 [[Effects:] [Attempt to obtain ownership for the current thread. Blocks until ownership can be obtained, or the specified time is
271 reached. If the specified time has already passed, behaves as __try_lock_ref__.]]
273 [[Synchronization:] [If `try_lock_until()` returns true, prior `unlock()` operations on the same object synchronize with this operation.]]
275 [[Return type:] [`bool`.]]
277 [[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
279 [[Postcondition:] [If the call returns `true`, the current thread owns `m`.]]
281 [[Throws:] [Nothing.]]
285 [section:try_lock_for `m.try_lock_for(rel_time)`]
289 [[Requires:] [The calling thread doesn't owns the mutex if the mutex is not recursive.]]
291 [[Effects:] [As-if `__try_lock_until(chrono::steady_clock::now() + rel_time)`.]]
293 [[Synchronization:] [If `try_lock_for()` returns true, prior `unlock()` operations on the same object synchronize with this operation.]]
299 DEPRECATED since 4.00. The following expressions were required on version 2, but are now deprecated.
301 Use instead __try_lock_for, __try_lock_until.
307 * `rel_time` denotes a value of an instantiation of an unspecified `DurationType` arithmetic compatible with `boost::system_time`, and
308 * `abs_time` denotes a value of an instantiation of `boost::system_time`:
312 * `m.__timed_lock_duration(rel_time)`
313 * `m.__timed_lock(abs_time)`
315 Lock ownership acquired through a call to __timed_lock_ref__ must be released through a call to __unlock_ref__.
317 [section:timed_lock `m.timed_lock(abs_time)`]
321 [[Effects:] [Attempt to obtain ownership for the current thread. Blocks until ownership can be obtained, or the specified time is
322 reached. If the specified time has already passed, behaves as __try_lock_ref__.]]
324 [[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
326 [[Postcondition:] [If the call returns `true`, the current thread owns `m`.]]
328 [[Throws:] [__lock_error__ if an error occurs.]]
332 [section:timed_lock_duration `m.timed_lock(rel_time)`]
336 [[Effects:] [As-if [timed_lock_ref_link
337 `timed_lock(boost::get_system_time()+rel_time)`].]]
345 [section:shared_lockable `SharedLockable` Concept -- C++14]
347 // #include <boost/thread/lockable_concepts.hpp>
352 class SharedLockable; // C++14
356 The __shared_lockable_concept__ is a refinement of the __timed_lockable_concept__ that
357 allows for ['shared ownership] as well as ['exclusive ownership]. This is the
358 standard multiple-reader / single-write model: at most one thread can have
359 exclusive ownership, and if any thread does have exclusive ownership, no other threads
360 can have shared or exclusive ownership. Alternatively, many threads may have
363 A type `L` meets the __SharedLockable requirements if it meets the __TimedLockable requirements and the following expressions are well-formed and have the specified semantics.
367 * `m` denotes a value of type `L`,
368 * `rel_time` denotes a value of an instantiation of `chrono::duration`, and
369 * `abs_time` denotes a value of an instantiation of `chrono::time_point`:
373 * `m.__lock_shared();`
374 * `m.__try_lock_shared()`
375 * `m.__try_lock_shared_for(rel_time)`
376 * `m.__try_lock_shared_until(abs_time)`
377 * `m.__unlock_shared();`
379 Lock ownership acquired through a call to __lock_shared_ref__, __try_lock_shared_ref__, __try_lock_shared_for or __try_lock_shared_until must be released through a call to __unlock_shared_ref__.
381 [section:lock_shared `m.lock_shared()`]
385 [[Effects:] [The current thread blocks until shared ownership can be obtained for the current thread.]]
387 [[Postcondition:] [The current thread has shared ownership of `m`.]]
389 [[Throws:] [__lock_error__ if an error occurs.]]
394 [section:try_lock_shared `m.try_lock_shared()`]
398 [[Effects:] [Attempt to obtain shared ownership for the current thread without blocking.]]
400 [[Returns:] [`true` if shared ownership was obtained for the current thread, `false` otherwise.]]
402 [[Postcondition:] [If the call returns `true`, the current thread has shared ownership of `m`.]]
404 [[Throws:] [__lock_error__ if an error occurs.]]
409 [section:try_lock_shared_for `m.try_lock_shared_for(rel_time)`]
413 [[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the
414 specified duration is elapsed. If the specified duration is already elapsed, behaves as __try_lock_shared_ref__.]]
416 [[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
418 [[Postcondition:] [If the call returns `true`, the current thread has shared
421 [[Throws:] [__lock_error__ if an error occurs.]]
426 [section:try_lock_shared_until `m.try_lock_shared_until(abs_time))`]
430 [[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the
431 specified time is reached. If the specified time has already passed, behaves as __try_lock_shared_ref__.]]
433 [[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
435 [[Postcondition:] [If the call returns `true`, the current thread has shared
438 [[Throws:] [__lock_error__ if an error occurs.]]
443 [section:unlock_shared `m.unlock_shared()`]
447 [[Precondition:] [The current thread has shared ownership of `m`.]]
449 [[Effects:] [Releases shared ownership of `m` by the current thread.]]
451 [[Postcondition:] [The current thread no longer has shared ownership of `m`.]]
453 [[Throws:] [Nothing]]
459 DEPRECATED since 3.00. The following expressions were required on version 2, but are now deprecated.
461 Use instead __try_lock_shared_for, __try_lock_shared_until.
466 * `abs_time` denotes a value of an instantiation of `boost::system_time`:
470 * `m.timed_lock_shared(abs_time);`
472 Lock ownership acquired through a call to __timed_lock_shared_ref__ must be released through a call to __unlock_shared_ref__.
474 [section:timed_lock_shared `m.timed_lock_shared(abs_time)`]
478 [[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the
479 specified time is reached. If the specified time has already passed, behaves as __try_lock_shared_ref__.]]
481 [[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
483 [[Postcondition:] [If the call returns `true`, the current thread has shared
486 [[Throws:] [__lock_error__ if an error occurs.]]
495 [section:upgrade_lockable `UpgradeLockable` Concept -- EXTENSION]
497 // #include <boost/thread/lockable_concepts.hpp>
502 class UpgradeLockable; // EXTENSION
506 The __upgrade_lockable_concept__ is a refinement of the __shared_lockable_concept__ that allows for ['upgradable ownership] as well
507 as ['shared ownership] and ['exclusive ownership]. This is an extension to the multiple-reader / single-write model provided by the
508 __shared_lockable_concept__: a single thread may have ['upgradable ownership] at the same time as others have ['shared
509 ownership]. The thread with ['upgradable ownership] may at any time attempt to upgrade that ownership to ['exclusive ownership]. If
510 no other threads have shared ownership, the upgrade is completed immediately, and the thread now has ['exclusive ownership], which
511 must be relinquished by a call to __unlock_ref__, just as if it had been acquired by a call to __lock_ref__.
513 If a thread with ['upgradable ownership] tries to upgrade whilst other threads have ['shared ownership], the attempt will fail and
514 the thread will block until ['exclusive ownership] can be acquired.
516 Ownership can also be ['downgraded] as well as ['upgraded]: exclusive ownership of an implementation of the
517 __upgrade_lockable_concept__ can be downgraded to upgradable ownership or shared ownership, and upgradable ownership can be
518 downgraded to plain shared ownership.
520 A type `L` meets the __UpgradeLockable requirements if it meets the __SharedLockable
521 requirements and the following expressions are well-formed and have the specified semantics.
525 * `m` denotes a value of type `L`,
526 * `rel_time` denotes a value of an instantiation of `chrono::duration`, and
527 * `abs_time` denotes a value of an instantiation of `chrono::time_point`:
531 * `m.__lock_upgrade();`
532 * `m.__unlock_upgrade()`
533 * `m.__try_lock_upgrade()`
534 * `m.__try_lock_upgrade_for(rel_time)`
535 * `m.__try_lock_upgrade_until(abs_time)`
536 * `m.__unlock_and_lock_shared()`
537 * `m.__unlock_and_lock_upgrade();`
538 * `m.__unlock_upgrade_and_lock();`
539 * `m.__try_unlock_upgrade_and_lock()`
540 * `m.__try_unlock_upgrade_and_lock_for(rel_time)`
541 * `m.__try_unlock_upgrade_and_lock_until(abs_time)`
542 * `m.__unlock_upgrade_and_lock_shared();`
545 If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION is defined the following expressions are also required:
547 * `m.__try_unlock_shared_and_lock();`
548 * `m.__try_unlock_shared_and_lock_for(rel_time);`
549 * `m.__try_unlock_shared_and_lock_until(abs_time);`
550 * `m.__try_unlock_shared_and_lock_upgrade();`
551 * `m.__try_unlock_shared_and_lock_upgrade_for(rel_time);`
552 * `m.__try_unlock_shared_and_lock_upgrade_until(abs_time);`
555 Lock ownership acquired through a call to __lock_upgrade_ref__ must be released through a call to __unlock_upgrade_ref__. If the
556 ownership type is changed through a call to one of the `unlock_xxx_and_lock_yyy()` functions, ownership must be released through a
557 call to the unlock function corresponding to the new level of ownership.
560 [section:lock_upgrade `m.lock_upgrade()`]
564 [[Precondition:] [The calling thread has no ownership of the mutex. ]]
566 [[Effects:] [The current thread blocks until upgrade ownership can be obtained for the current thread.]]
568 [[Postcondition:] [The current thread has upgrade ownership of `m`.]]
570 [[Synchronization:] [Prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
572 [[Throws:] [__lock_error__ if an error occurs.]]
577 [section:unlock_upgrade `m.unlock_upgrade()`]
581 [[Precondition:] [The current thread has upgrade ownership of `m`.]]
583 [[Effects:] [Releases upgrade ownership of `m` by the current thread.]]
585 [[Postcondition:] [The current thread no longer has upgrade ownership of `m`.]]
587 [[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership on the same object.]]
589 [[Throws:] [Nothing]]
594 [section:try_lock_upgrade `m.try_lock_upgrade()`]
598 [[Precondition:] [The calling thread has no ownership of the mutex. ]]
600 [[Effects:] [Attempts to obtain upgrade ownership of the mutex for the calling thread without blocking. If upgrade ownership is not obtained, there is no effect and try_lock_upgrade() immediately returns.]]
602 [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
604 [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
606 [[Synchronization:] [If `__try_lock_upgrade()` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
608 [[Throws:] [Nothing]]
614 [section:try_lock_upgrade_for `m.try_lock_upgrade_for(rel_time)`]
618 [[Precondition:] [The calling thread has no ownership of the mutex. ]]
620 [[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
621 Attempts to obtain upgrade lock ownership for the calling thread within the relative timeout specified by `rel_time`.
622 If the time specified by `rel_time` is less than or equal to `rel_time.zero()`, the function attempts to obtain ownership without blocking (as if by calling `__try_lock_upgrade()`).
623 The function returns within the timeout specified by `rel_time` only if it has obtained upgrade ownership of the mutex object.]]
625 [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
627 [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
629 [[Synchronization:] [If `__try_lock_upgrade_for(rel_time)` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
631 [[Throws:] [Nothing]]
633 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
638 [section:try_lock_upgrade_until `m.try_lock_upgrade_until(abs_time)`]
642 [[Precondition:] [The calling thread has no ownership of the mutex. ]]
644 [[Effects:] [The function attempts to obtain upgrade ownership of the mutex.
645 If `abs_time` has already passed, the function attempts to obtain upgrade ownership without blocking (as if by calling `__try_lock_upgrade()`).
646 The function returns before the absolute timeout specified by `abs_time` only if it has obtained upgrade ownership of the mutex object.]]
648 [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
650 [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
652 [[Synchronization:] [If `__try_lock_upgrade_until(abs_time)` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
654 [[Throws:] [Nothing]]
656 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
662 [section:try_unlock_shared_and_lock `m.try_unlock_shared_and_lock()`]
666 [[Precondition:] [The calling thread must hold a shared lock on the mutex.]]
668 [[Effects:] [The function attempts to atomically convert the ownership from shared to exclusive for the calling thread without blocking.
669 For this conversion to be successful, this thread must be the only thread holding any ownership of the lock.
670 If the conversion is not successful, the shared ownership of m is retained.]]
672 [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
674 [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
676 [[Synchronization:] [If `__try_unlock_shared_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
679 [[Throws:] [Nothing]]
681 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
686 [section:try_unlock_shared_and_lock_for `m.try_unlock_shared_and_lock_for(rel_time)`]
690 [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
692 [[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
693 The function attempts to atomically convert the ownership from shared to exclusive for the calling thread within the relative timeout specified by `rel_time`.
694 If the time specified by `rel_time` is less than or equal to `rel_time.zero()`, the function attempts to obtain exclusive ownership without blocking (as if by calling `try_unlock_shared_and_lock()`).
695 The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object.
696 For this conversion to be successful, this thread must be the only thread holding any ownership of the lock at the moment of conversion.
697 If the conversion is not successful, the shared ownership of the mutex is retained.]]
699 [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
701 [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
703 [[Synchronization:] [If `__try_unlock_shared_and_lock_for(rel_time)` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
705 [[Throws:] [Nothing]]
707 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
713 [section:try_unlock_shared_and_lock_until `m.try_unlock_shared_and_lock_until(abs_time)`]
717 [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
719 [[Effects:] [The function attempts to atomically convert the ownership from shared to exclusive for the calling thread within the absolute timeout specified by `abs_time`.
720 If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `try_unlock_shared_and_lock()`).
721 The function shall return before the absolute timeout specified by `abs_time` only if it has obtained exclusive ownership of the mutex object.
722 For this conversion to be successful, this thread must be the only thread holding any ownership of the lock at the moment of conversion.
723 If the conversion is not successful, the shared ownership of the mutex is retained.]]
725 [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
727 [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
729 [[Synchronization:] [If `__try_unlock_shared_and_lock_until(rel_time)` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
731 [[Throws:] [Nothing]]
733 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
738 [section:unlock_and_lock_shared `m.unlock_and_lock_shared()`]
742 [[Precondition:] [The calling thread shall hold an exclusive lock on `m`.]]
744 [[Effects:] [Atomically converts the ownership from exclusive to shared for the calling thread.]]
746 [[Postcondition:] [The current thread has shared ownership of `m`.]]
748 [[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership of the same object.]]
750 [[Throws:] [Nothing]]
755 [section:try_unlock_shared_and_lock_upgrade `m.try_unlock_shared_and_lock_upgrade()`]
759 [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
761 [[Effects:] [The function attempts to atomically convert the ownership from shared to upgrade for the calling thread without blocking.
762 For this conversion to be successful, there must be no thread holding upgrade ownership of this object.
763 If the conversion is not successful, the shared ownership of the mutex is retained.]]
765 [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
767 [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
769 [[Synchronization:] [If `__try_unlock_shared_and_lock_upgrade()` returns true, prior `__unlock_upgrade()` and subsequent lock operations on the same object synchronize with this operation. ]]
771 [[Throws:] [Nothing]]
773 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
779 [section:try_unlock_shared_and_lock_upgrade_for `m.try_unlock_shared_and_lock_upgrade_for(rel_time)`]
783 [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
785 [[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
786 The function attempts to atomically convert the ownership from shared to upgrade for the calling thread within the relative timeout specified by `rel_time`.
787 If the time specified by `rel_time` is less than or equal to `rel_time.zero()`, the function attempts to obtain upgrade ownership without blocking (as if by calling `__try_unlock_shared_and_lock_upgrade()`).
788 The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object.
789 For this conversion to be successful, there must be no thread holding upgrade ownership of this object at the moment of conversion.
790 If the conversion is not successful, the shared ownership of m is retained.]]
792 [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
794 [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
796 [[Synchronization:] [If `__try_unlock_shared_and_lock_upgrade_for(rel_time)` returns true, prior `__unlock_upgrade()` and subsequent lock operations on the same object synchronize with this operation. ]]
798 [[Throws:] [Nothing]]
800 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
806 [section:try_unlock_shared_and_lock_upgrade_until `m.try_unlock_shared_and_lock_upgrade_until(abs_time)`]
810 [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
812 [[Effects:] [The function attempts to atomically convert the ownership from shared to upgrade for the calling thread within the absolute timeout specified by `abs_time`.
813 If `abs_time` has already passed, the function attempts to obtain upgrade ownership without blocking (as if by calling `__try_unlock_shared_and_lock_upgrade()`).
814 The function shall return before the absolute timeout specified by `abs_time` only if it has obtained upgrade ownership of the mutex object.
815 For this conversion to be successful, there must be no thread holding upgrade ownership of this object at the moment of conversion.
816 If the conversion is not successful, the shared ownership of the mutex is retained.]]
818 [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
820 [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
822 [[Synchronization:] [If `__try_unlock_shared_and_lock_upgrade_until(rel_time)` returns true, prior `__unlock_upgrade()` and subsequent lock operations on the same object synchronize with this operation. ]]
824 [[Throws:] [Nothing]]
826 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
831 [section:unlock_and_lock_upgrade `m.unlock_and_lock_upgrade()`]
835 [[Precondition:] [The current thread has exclusive ownership of `m`.]]
837 [[Effects:] [Atomically releases exclusive ownership of `m` by the current thread and acquires upgrade ownership of `m`
840 [[Postcondition:] [The current thread has upgrade ownership of `m`.]]
842 [[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership of the same object.]]
844 [[Throws:] [Nothing]]
850 [section:unlock_upgrade_and_lock `m.unlock_upgrade_and_lock()`]
854 [[Precondition:] [The current thread has upgrade ownership of `m`.]]
856 [[Effects:] [Atomically releases upgrade ownership of `m` by the current thread and acquires exclusive ownership of `m`. If
857 any other threads have shared ownership, blocks until exclusive ownership can be acquired.]]
859 [[Postcondition:] [The current thread has exclusive ownership of `m`.]]
861 [[Synchronization:] [This operation synchronizes with prior `__unlock_shared()` and subsequent lock operations that obtain ownership of the same object.]]
863 [[Throws:] [Nothing]]
868 [section:try_unlock_upgrade_and_lock `m.try_unlock_upgrade_and_lock()`]
872 [[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
874 [[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread without blocking.
875 For this conversion to be successful, this thread must be the only thread holding any ownership of the lock.
876 If the conversion is not successful, the upgrade ownership of m is retained.]]
878 [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
880 [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
882 [[Synchronization:] [If `__try_unlock_upgrade_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
884 [[Throws:] [Nothing]]
886 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
892 [section:try_unlock_upgrade_and_lock_for `m.try_unlock_upgrade_and_lock_for(rel_time)`]
896 [[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
898 [[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
899 The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the relative timeout specified by `rel_time`.
900 If the time specified by `rel_time` is less than or equal to `rel_time.zero()`, the function attempts to obtain exclusive ownership without blocking (as if by calling `__try_unlock_upgrade_and_lock()`).
901 The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object.
902 For this conversion to be successful, this thread shall be the only thread holding any ownership of the lock at the moment of conversion.
903 If the conversion is not successful, the upgrade ownership of m is retained.]]
905 [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
907 [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
909 [[Synchronization:] [If `__try_unlock_upgrade_and_lock_for(rel_time)` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
911 [[Throws:] [Nothing]]
913 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
918 [section:try_unlock_upgrade_and_lock_until `m.try_unlock_upgrade_and_lock_until(abs_time)`]
922 [[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
924 [[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the absolute timeout specified by `abs_time`.
925 If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `__try_unlock_upgrade_and_lock()`).
926 The function shall return before the absolute timeout specified by `abs_time` only if it has obtained exclusive ownership of the mutex object.
927 For this conversion to be successful, this thread shall be the only thread holding any ownership of the lock at the moment of conversion.
928 If the conversion is not successful, the upgrade ownership of m is retained.]]
930 [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
932 [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
934 [[Synchronization:] [If `__try_unlock_upgrade_and_lock_for(rel_time)` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
936 [[Throws:] [Nothing]]
938 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
944 [section:unlock_upgrade_and_lock_shared `m.unlock_upgrade_and_lock_shared()`]
948 [[Precondition:] [The current thread has upgrade ownership of `m`.]]
950 [[Effects:] [Atomically releases upgrade ownership of `m` by the current thread and acquires shared ownership of `m` without
953 [[Postcondition:] [The current thread has shared ownership of `m`.]]
955 [[Synchronization:] [This operation synchronizes with prior `unlock_shared()` and subsequent lock operations that obtain ownership of the same object.]]
957 [[Throws:] [Nothing]]
966 [section:lock_option Lock Options]
968 // #include <boost/thread/locks.hpp>
969 // #include <boost/thread/locks_options.hpp>
973 struct defer_lock_t {};
974 struct try_to_lock_t {};
975 struct adopt_lock_t {};
976 constexpr defer_lock_t defer_lock;
977 constexpr try_to_lock_t try_to_lock;
978 constexpr adopt_lock_t adopt_lock;
980 [section:lock_tags Lock option tags]
982 #include <boost/thread/locks.hpp>
983 #include <boost/thread/locks_options.hpp>
985 struct defer_lock_t {};
986 struct try_to_lock_t {};
987 struct adopt_lock_t {};
988 const defer_lock_t defer_lock;
989 const try_to_lock_t try_to_lock;
990 const adopt_lock_t adopt_lock;
992 These tags are used in scoped locks constructors to specify a specific behavior.
994 *`defer_lock_t`: is used to construct the scoped lock without locking it.
995 *`try_to_lock_t`: is used to construct the scoped lock trying to lock it.
996 *`adopt_lock_t`: is used to construct the scoped lock without locking it but adopting ownership.
1002 [section:lock_guard Lock Guard]
1004 // #include <boost/thread/locks.hpp>
1005 // #include <boost/thread/lock_guard.hpp>
1010 template<typename Lockable>
1012 #if ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD
1013 template <typename Lockable>
1014 lock_guard<Lockable> make_lock_guard(Lockable& mtx); // EXTENSION
1015 template <typename Lockable>
1016 lock_guard<Lockable> make_lock_guard(Lockable& mtx, adopt_lock_t); // EXTENSION
1020 [section:lock_guard Class template `lock_guard`]
1022 // #include <boost/thread/locks.hpp>
1023 // #include <boost/thread/lock_guard.hpp>
1025 template<typename Lockable>
1029 explicit lock_guard(Lockable& m_);
1030 lock_guard(Lockable& m_,boost::adopt_lock_t);
1035 __lock_guard__ is very simple: on construction it
1036 acquires ownership of the implementation of the __lockable_concept__ supplied as
1037 the constructor parameter. On destruction, the ownership is released. This
1038 provides simple RAII-style locking of a __lockable_concept_type__ object, to facilitate exception-safe
1039 locking and unlocking. In addition, the [link
1040 thread.synchronization.lock_guard.lock_guard.constructor_adopt `lock_guard(Lockable &
1041 m,boost::adopt_lock_t)` constructor] allows the __lock_guard__ object to
1042 take ownership of a lock already held by the current thread.
1044 [section:constructor `lock_guard(Lockable & m)`]
1048 [[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
1050 [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
1056 [section:constructor_adopt `lock_guard(Lockable & m,boost::adopt_lock_t)`]
1060 [[Precondition:] [The current thread owns a lock on `m` equivalent to one
1061 obtained by a call to [lock_ref_link `m.lock()`].]]
1063 [[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of
1066 [[Throws:] [Nothing.]]
1072 [section:destructor `~lock_guard()`]
1076 [[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
1077 object passed to the constructor.]]
1079 [[Throws:] [Nothing.]]
1087 [section:make_lock_guard Non Member Function `make_lock_guard`]
1089 template <typename Lockable>
1090 lock_guard<Lockable> make_lock_guard(Lockable& m); // EXTENSION
1095 [[Returns:] [a lock_guard as if initialized with `{m}`.]]
1097 [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
1103 [section:make_lock_guard_adopt Non Member Function `make_lock_guard`]
1105 template <typename Lockable>
1106 lock_guard<Lockable> make_lock_guard(Lockable& m, adopt_lock_t); // EXTENSION
1111 [[Returns:] [a lock_guard as if initialized with `{m, adopt_lock}`.]]
1113 [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
1122 [section:with_lock_guard With Lock Guard]
1124 // #include <boost/thread/with_lock_guard.hpp>
1128 template <class Lockable, class Function, class... Args>
1129 auto with_lock_guard(Lockable& m, Function&& func, Args&&... args) -> decltype(func(boost::forward<Args>(args)...));
1132 [section:with_lock_guard Non Member Function `with_lock_guard`]
1134 template <class Lockable, class Function, class... Args>
1135 auto with_lock_guard(
1139 ) -> decltype(func(boost::forward<Args>(args)...));
1143 [[Precondition:] [`m` must be in unlocked state]]
1144 [[Effects:] [call `func` in scope locked by `m`]]
1145 [[Returns:] [Result of `func(args...)` call]]
1146 [[Throws:] [Any exception thrown by the call to `m.lock` and `func(args...)`]]
1147 [[Postcondition:] [`m` is in unlocked state]]
1149 [[Limitations:] [Without c++11 variadic templates support number of arguments is limited to `4`]]
1150 [[] [Without rvalue references support calling class method with `boost::bind` must be const]]
1151 [[] [For correct work with lambda macro `BOOST_RESULT_OF_USE_DECLTYPE` may be needed to define]]
1159 [section:lock_concepts Lock Concepts]
1160 [section:StrictLock StrictLock -- EXTENSION]
1162 // #include <boost/thread/lock_concepts.hpp>
1167 template<typename Lock>
1172 A StrictLock is a lock that ensures that the associated mutex is locked during the lifetime of the lock.
1174 A type `L` meets the StrictLock requirements if the following expressions are well-formed and have the specified semantics
1177 * `is_strict_lock<L>`
1178 * `cl.owns_lock(m);`
1180 and BasicLockable<L::mutex_type>
1184 * `cl` denotes a value of type `L const&`,
1185 * `m` denotes a value of type `L::mutex_type const*`,
1187 [section: mutex_type `L::mutex_type`]
1189 The type L::mutex_type denotes the mutex that is locked by this lock.
1191 [endsect] [/ mutex_type]
1193 [section:is_strict_lock_sur_parole `is_strict_lock_sur_parole<L>`]
1195 As the semantic "ensures that the associated mutex is locked during the lifetime of the lock. " can not be described by syntactic requirements a `is_strict_lock_sur_parole` trait must be specialized by the user defining the lock so that the following assertion is true:
1197 is_strict_lock_sur_parole<L>::value == true
1199 [endsect] [/ is_strict_lock_sur_parole]
1201 [section:owns_lock `cl.owns_lock(m);`]
1205 [[Return Type:] [`bool`]]
1206 [[Returns:] [Whether the strict lock is locking the mutex `m`]]
1208 [[Throws:] [Nothing.]]
1213 [endsect] [/ owns_lock]
1217 The following classes are models of `StrictLock`:
1219 * strict_lock: ensured by construction,
1220 * nested_strict_lock: "sur parole" as the user could use adopt_lock_t on unique_lock constructor overload without having locked the mutex,
1221 * __lock_guard__: "sur parole" as the user could use adopt_lock_t constructor overload without having locked the mutex.
1223 [endsect] [/ Models]
1225 [endsect] [/ Strict Lock]
1227 [endsect] [/ Lock Concepts]
1229 [section:locks Lock Types]
1231 // #include <boost/thread/locks.hpp>
1232 // #include <boost/thread/lock_types.hpp>
1237 template<typename Lockable>
1239 template<typename Mutex>
1240 void swap(unique_lock <Mutex>& lhs, unique_lock <Mutex>& rhs);
1241 template<typename Lockable>
1242 class shared_lock; // C++14
1243 template<typename Mutex>
1244 void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs); // C++14
1245 template<typename Lockable>
1246 class upgrade_lock; // EXTENSION
1247 template<typename Mutex>
1248 void swap(upgrade_lock <Mutex>& lhs, upgrade_lock <Mutex>& rhs); // EXTENSION
1249 template <class Mutex>
1250 class upgrade_to_unique_lock; // EXTENSION
1255 [section:unique_lock Class template `unique_lock`]
1257 // #include <boost/thread/locks.hpp>
1258 // #include <boost/thread/lock_types.hpp>
1260 template<typename Lockable>
1264 typedef Lockable mutex_type;
1265 unique_lock() noexcept;
1266 explicit unique_lock(Lockable& m_);
1267 unique_lock(Lockable& m_,adopt_lock_t);
1268 unique_lock(Lockable& m_,defer_lock_t) noexcept;
1269 unique_lock(Lockable& m_,try_to_lock_t);
1271 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
1272 unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t); // C++14
1273 template <class Clock, class Duration>
1274 unique_lock(shared_lock<mutex_type>&& sl,
1275 const chrono::time_point<Clock, Duration>& abs_time); // C++14
1276 template <class Rep, class Period>
1277 unique_lock(shared_lock<mutex_type>&& sl,
1278 const chrono::duration<Rep, Period>& rel_time); // C++14
1281 template <class Clock, class Duration>
1282 unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t);
1283 template <class Rep, class Period>
1284 unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d);
1287 unique_lock(unique_lock const&) = delete;
1288 unique_lock& operator=(unique_lock const&) = delete;
1289 unique_lock(unique_lock<Lockable>&& other) noexcept;
1290 explicit unique_lock(upgrade_lock<Lockable>&& other) noexcept; // EXTENSION
1292 unique_lock& operator=(unique_lock<Lockable>&& other) noexcept;
1294 void swap(unique_lock& other) noexcept;
1295 Lockable* release() noexcept;
1300 template <class Rep, class Period>
1301 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
1302 template <class Clock, class Duration>
1303 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
1307 explicit operator bool() const noexcept;
1308 bool owns_lock() const noexcept;
1310 mutex_type* mutex() const noexcept;
1312 #if defined BOOST_THREAD_USE_DATE_TIME || defined BOOST_THREAD_DONT_USE_CHRONO
1313 unique_lock(Lockable& m_,system_time const& target_time);
1314 template<typename TimeDuration>
1315 bool timed_lock(TimeDuration const& relative_time);
1316 bool timed_lock(::boost::system_time const& absolute_time);
1321 __unique_lock__ is more complex than __lock_guard__: not only does it provide for RAII-style locking, it also allows for deferring
1322 acquiring the lock until the __lock_ref__ member function is called explicitly, or trying to acquire the lock in a non-blocking
1323 fashion, or with a timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the
1324 __lockable_concept_type__ object, or otherwise adopted a lock on the __lockable_concept_type__ object.
1326 Specializations of __unique_lock__ model the __TimedLockable concept if the supplied `Lockable` type itself models
1327 __TimedLockable concept (e.g. `boost::unique_lock<boost::timed_mutex>`), or the __Lockable concept if the supplied `Lockable` type itself models
1328 __Lockable concept (e.g. `boost::unique_lock<boost::mutex>`), or the __BasicLockable concept if the supplied `Lockable` type itself models
1329 __BasicLockable concept.
1331 An instance of __unique_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
1332 pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
1333 is destroyed, then the destructor will invoke [unlock_ref_link `mutex()->unlock()`].
1335 The member functions of __unique_lock__ are not thread-safe. In particular, __unique_lock__ is intended to model the ownership of a
1336 __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock state
1337 (including the destructor) must be called by the same thread that acquired ownership of the lock state.
1339 [section:defaultconstructor `unique_lock()`]
1343 [[Effects:] [Creates a lock object with no associated mutex.]]
1345 [[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `NULL`.]]
1347 [[Throws:] [Nothing.]]
1353 [section:constructor `unique_lock(Lockable & m)`]
1357 [[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
1359 [[Postcondition:] [__owns_lock_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
1361 [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
1367 [section:constructor_adopt `unique_lock(Lockable & m,boost::adopt_lock_t)`]
1371 [[Precondition:] [The current thread owns an exclusive lock on `m`.]]
1373 [[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of `m`.]]
1375 [[Postcondition:] [__owns_lock_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
1377 [[Throws:] [Nothing.]]
1383 [section:constructor_defer `unique_lock(Lockable & m,boost::defer_lock_t)`]
1387 [[Effects:] [Stores a reference to `m`.]]
1389 [[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `&m`.]]
1391 [[Throws:] [Nothing.]]
1397 [section:constructor_try `unique_lock(Lockable & m,boost::try_to_lock_t)`]
1401 [[Effects:] [Stores a reference to `m`. Invokes [try_lock_ref_link
1402 `m.try_lock()`], and takes ownership of the lock state if the call returns
1405 [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_ref__
1406 returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
1409 [[Throws:] [Nothing.]]
1415 [section:constructor_sh_try `unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)`]
1419 [[Requires:] [The supplied `Mutex` type must implement `__try_unlock_shared_and_lock()`.]]
1421 [[Effects:] [Constructs an object of type __unique_lock. Let `pm` be the pointer to the mutex and `owns` the ownership state. Initializes `pm` with nullptr and `owns` with false.
1422 If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.release()`.
1423 Else `sl.__owns_lock()` returns `true`, and in this case if `sl.mutex()->try_unlock_shared_and_lock()` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
1425 [[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()->try_unlock_shared_and_lock()` returns `false`, `sl` is not modified.]]
1427 [[Throws:] [Nothing.]]
1429 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
1436 [section:constructor_sh_until `unique_lock(shared_lock<mutex_type>&&, const chrono::time_point<Clock, Duration>&)`]
1438 template <class Clock, class Duration>
1439 unique_lock(shared_lock<mutex_type>&& sl,
1440 const chrono::time_point<Clock, Duration>& abs_time);
1444 [[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_until(abs_time)`.]]
1446 [[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
1447 If `sl.__owns_lock_shared_ref__()` returns `false`, sets `pm` to the return value of `sl.release()`.
1448 Else `sl.__owns_lock_shared_ref__()` returns `true`, and in this case if `sl.mutex()->__try_unlock_shared_and_lock_until(abs_time)` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
1450 [[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_until(abs_time)` returns `false`, `sl` is not modified.]]
1452 [[Throws:] [Nothing.]]
1454 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
1460 [section:constructor_sh_for `unique_lock(shared_lock<mutex_type>&&, const chrono::duration<Rep, Period>&)`]
1462 template <class Rep, class Period>
1463 unique_lock(shared_lock<mutex_type>&& sl,
1464 const chrono::duration<Rep, Period>& rel_time)
1468 [[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_for(rel_time)`.]]
1470 [[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
1471 If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.release()`.
1472 Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
1474 [[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `false`, `sl` is not modified.]]
1477 [[Postcondition:] [.]]
1479 [[Throws:] [Nothing.]]
1481 [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
1491 [section:constructor_abs_time `unique_lock(Lockable & m,boost::system_time const& abs_time)`]
1495 [[Effects:] [Stores a reference to `m`. Invokes [timed_lock_ref_link
1496 `m.timed_lock(abs_time)`], and takes ownership of the lock state if the call
1499 [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __timed_lock_ref__
1500 returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
1503 [[Throws:] [Any exceptions thrown by the call to [timed_lock_ref_link `m.timed_lock(abs_time)`].]]
1509 [section:constructor_time_point `template <class Clock, class Duration> unique_lock(Lockable & m,const chrono::time_point<Clock, Duration>& abs_time)`]
1513 [[Effects:] [Stores a reference to `m`. Invokes
1514 `m.__try_lock_until(abs_time)`, and takes ownership of the lock state if the call
1517 [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_until
1518 returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
1521 [[Throws:] [Any exceptions thrown by the call to `m.__try_lock_until(abs_time)`.]]
1527 [section:constructor_duration `template <class Rep, class Period> unique_lock(Lockable & m,const chrono::duration<Rep, Period>& abs_time)`]
1532 [[Effects:] [Stores a reference to `m`. Invokes
1533 `m.__try_lock_for(rel_time)`, and takes ownership of the lock state if the call
1536 [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_for
1537 returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
1540 [[Throws:] [Any exceptions thrown by the call to `m.__try_lock_for(rel_time)`.]]
1546 [section:destructor `~unique_lock()`]
1550 [[Effects:] [Invokes __mutex_func_ref__`->`[unlock_ref_link `unlock()`] if
1551 __owns_lock_ref__ returns `true`.]]
1553 [[Throws:] [Nothing.]]
1559 [section:owns_lock `bool owns_lock() const`]
1563 [[Returns:] [`true` if the `*this` owns the lock on the __lockable_concept_type__
1564 object associated with `*this`.]]
1566 [[Throws:] [Nothing.]]
1572 [section:mutex `Lockable* mutex() const noexcept`]
1576 [[Returns:] [A pointer to the __lockable_concept_type__ object associated with
1577 `*this`, or `NULL` if there is no such object.]]
1579 [[Throws:] [Nothing.]]
1585 [section:explicit_bool_conversion `explicit operator bool() const`]
1589 [[Returns:] [`__owns_lock_ref__()`.]]
1591 [[Throws:] [Nothing.]]
1598 [section:release `Lockable* release()`]
1602 [[Effects:] [The association between `*this` and the __lockable_concept_type__ object is removed, without affecting the lock state
1603 of the __lockable_concept_type__ object. If __owns_lock_ref__ would have returned `true`, it is the responsibility of the calling
1604 code to ensure that the __lockable_concept_type__ is correctly unlocked.]]
1606 [[Returns:] [A pointer to the __lockable_concept_type__ object associated with `*this` at the point of the call, or `NULL` if there
1607 is no such object.]]
1609 [[Throws:] [Nothing.]]
1611 [[Postcondition:] [`*this` is no longer associated with any __lockable_concept_type__ object. __mutex_func_ref__ returns `NULL` and
1612 __owns_lock_ref__ returns `false`.]]
1620 [section:shared_lock Class template `shared_lock` - C++14]
1622 // #include <boost/thread/locks.hpp>
1623 // #include <boost/thread/lock_types.hpp>
1625 template<typename Lockable>
1629 typedef Lockable mutex_type;
1633 explicit shared_lock(Lockable& m_);
1634 shared_lock(Lockable& m_,adopt_lock_t);
1635 shared_lock(Lockable& m_,defer_lock_t);
1636 shared_lock(Lockable& m_,try_to_lock_t);
1637 template <class Clock, class Duration>
1638 shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t);
1639 template <class Rep, class Period>
1640 shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d);
1643 shared_lock(shared_lock const&) = delete;
1644 shared_lock& operator=(shared_lock const&) = delete;
1646 shared_lock(shared_lock<Lockable> && other);
1647 shared_lock& operator=(shared_lock<Lockable> && other);
1651 template <class Rep, class Period>
1652 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
1653 template <class Clock, class Duration>
1654 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
1657 // Conversion from upgrade locking
1658 explicit shared_lock(upgrade_lock<Lockable> && other); // EXTENSION
1660 // Conversion from exclusive locking
1661 explicit shared_lock(unique_lock<Lockable> && other);
1664 void swap(shared_lock& other);
1665 mutex_type* release() noexcept;
1668 explicit operator bool() const;
1669 bool owns_lock() const;
1670 mutex_type mutex() const;
1672 #if defined BOOST_THREAD_USE_DATE_TIME || defined BOOST_THREAD_DONT_USE_CHRONO
1673 shared_lock(Lockable& m_,system_time const& target_time);
1674 bool timed_lock(boost::system_time const& target_time);
1678 Like __unique_lock__, __shared_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
1679 __lockable_concept_type__ object, locking an instance of __shared_lock__ acquires shared ownership.
1681 Like __unique_lock__, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the
1682 __lock_ref__ member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a
1683 timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the __lockable_concept_type__
1684 object, or otherwise adopted a lock on the __lockable_concept_type__ object.
1686 An instance of __shared_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
1687 pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
1688 is destroyed, then the destructor will invoke [unlock_shared_ref_link `mutex()->unlock_shared()`].
1690 The member functions of __shared_lock__ are not thread-safe. In particular, __shared_lock__ is intended to model the shared
1691 ownership of a __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
1692 state (including the destructor) must be called by the same thread that acquired ownership of the lock state.
1694 [section:defaultconstructor `shared_lock()`]
1698 [[Effects:] [Creates a lock object with no associated mutex.]]
1700 [[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `NULL`.]]
1702 [[Throws:] [Nothing.]]
1708 [section:constructor `shared_lock(Lockable & m)`]
1712 [[Effects:] [Stores a reference to `m`. Invokes [lock_shared_ref_link `m.lock_shared()`].]]
1714 [[Postcondition:] [__owns_lock_shared_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
1716 [[Throws:] [Any exception thrown by the call to [lock_shared_ref_link `m.lock_shared()`].]]
1722 [section:constructor_adopt `shared_lock(Lockable & m,boost::adopt_lock_t)`]
1726 [[Precondition:] [The current thread owns an exclusive lock on `m`.]]
1728 [[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of `m`.]]
1730 [[Postcondition:] [__owns_lock_shared_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
1732 [[Throws:] [Nothing.]]
1738 [section:constructor_defer `shared_lock(Lockable & m,boost::defer_lock_t)`]
1742 [[Effects:] [Stores a reference to `m`.]]
1744 [[Postcondition:] [__owns_lock_shared_ref__ returns `false`. __mutex_func_ref__ returns `&m`.]]
1746 [[Throws:] [Nothing.]]
1752 [section:constructor_try `shared_lock(Lockable & m,boost::try_to_lock_t)`]
1756 [[Effects:] [Stores a reference to `m`. Invokes [try_lock_shared_ref_link
1757 `m.try_lock_shared()`], and takes ownership of the lock state if the call returns
1760 [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_shared_ref__
1761 returned `true`, then __owns_lock_shared_ref__ returns `true`, otherwise __owns_lock_shared_ref__
1764 [[Throws:] [Nothing.]]
1770 [section:constructor_abs_time `shared_lock(Lockable & m,boost::system_time const& abs_time)`]
1774 [[Effects:] [Stores a reference to `m`. Invokes [timed_lock_shared_ref_link
1775 `m.timed_lock(abs_time)`], and takes ownership of the lock state if the call
1778 [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __timed_lock_shared_ref__
1779 returned `true`, then __owns_lock_shared_ref__ returns `true`, otherwise __owns_lock_shared_ref__
1782 [[Throws:] [Any exceptions thrown by the call to [timed_lock_shared_ref_link `m.timed_lock(abs_time)`].]]
1788 [section:destructor `~shared_lock()`]
1792 [[Effects:] [Invokes __mutex_func_ref__`->`[unlock_shared_ref_link `unlock_shared()`] if
1793 __owns_lock_shared_ref__ returns `true`.]]
1795 [[Throws:] [Nothing.]]
1801 [section:owns_lock `bool owns_lock() const`]
1805 [[Returns:] [`true` if the `*this` owns the lock on the __lockable_concept_type__
1806 object associated with `*this`.]]
1808 [[Throws:] [Nothing.]]
1814 [section:mutex `Lockable* mutex() const`]
1818 [[Returns:] [A pointer to the __lockable_concept_type__ object associated with
1819 `*this`, or `NULL` if there is no such object.]]
1821 [[Throws:] [Nothing.]]
1828 [section:explicit_operator_bool `explicit operator bool() const`]
1832 [[Returns:] [__owns_lock_shared_ref__.]]
1834 [[Throws:] [Nothing.]]
1840 [section:release `Lockable* release()`]
1844 [[Effects:] [The association between `*this` and the __lockable_concept_type__ object is removed, without affecting the lock state
1845 of the __lockable_concept_type__ object. If __owns_lock_shared_ref__ would have returned `true`, it is the responsibility of the calling
1846 code to ensure that the __lockable_concept_type__ is correctly unlocked.]]
1848 [[Returns:] [A pointer to the __lockable_concept_type__ object associated with `*this` at the point of the call, or `NULL` if there
1849 is no such object.]]
1851 [[Throws:] [Nothing.]]
1853 [[Postcondition:] [`*this` is no longer associated with any __lockable_concept_type__ object. __mutex_func_ref__ returns `NULL` and
1854 __owns_lock_shared_ref__ returns `false`.]]
1862 [section:upgrade_lock Class template `upgrade_lock` - EXTENSION]
1864 // #include <boost/thread/locks.hpp>
1865 // #include <boost/thread/lock_types.hpp>
1867 template<typename Lockable>
1871 typedef Lockable mutex_type;
1876 explicit upgrade_lock(mutex_type& m_);
1877 upgrade_lock(mutex_type& m, defer_lock_t) noexcept;
1878 upgrade_lock(mutex_type& m, try_to_lock_t);
1879 upgrade_lock(mutex_type& m, adopt_lock_t);
1880 template <class Clock, class Duration>
1881 upgrade_lock(mutex_type& m,
1882 const chrono::time_point<Clock, Duration>& abs_time);
1883 template <class Rep, class Period>
1884 upgrade_lock(mutex_type& m,
1885 const chrono::duration<Rep, Period>& rel_time);
1888 upgrade_lock(const upgrade_lock& other) = delete;
1889 upgrade_lock& operator=(const upgrade_lock<Lockable> & other) = delete;
1891 upgrade_lock(upgrade_lock<Lockable> && other);
1892 upgrade_lock& operator=(upgrade_lock<Lockable> && other);
1896 template <class Rep, class Period>
1897 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
1898 template <class Clock, class Duration>
1899 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
1902 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
1903 // Conversion from shared locking
1904 upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t);
1905 template <class Clock, class Duration>
1906 upgrade_lock(shared_lock<mutex_type>&& sl,
1907 const chrono::time_point<Clock, Duration>& abs_time);
1908 template <class Rep, class Period>
1909 upgrade_lock(shared_lock<mutex_type>&& sl,
1910 const chrono::duration<Rep, Period>& rel_time);
1913 // Conversion from exclusive locking
1914 explicit upgrade_lock(unique_lock<Lockable> && other);
1917 void swap(upgrade_lock& other);
1918 mutex_type* release() noexcept;
1921 explicit operator bool() const;
1922 bool owns_lock() const;
1923 mutex_type mutex() const;
1926 Like __unique_lock__, __upgrade_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
1927 __lockable_concept_type__ object, locking an instance of __upgrade_lock__ acquires upgrade ownership.
1929 Like __unique_lock__, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the
1930 __lock_ref__ member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a
1931 timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the __lockable_concept_type__
1932 object, or otherwise adopted a lock on the __lockable_concept_type__ object.
1934 An instance of __upgrade_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
1935 pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
1936 is destroyed, then the destructor will invoke [unlock_upgrade_ref_link `mutex()->unlock_upgrade()`].
1938 The member functions of __upgrade_lock__ are not thread-safe. In particular, __upgrade_lock__ is intended to model the upgrade
1939 ownership of a __upgrade_lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
1940 state (including the destructor) must be called by the same thread that acquired ownership of the lock state.
1944 [section:upgrade_to_unique_lock Class template `upgrade_to_unique_lock` -- EXTENSION]
1946 // #include <boost/thread/locks.hpp>
1947 // #include <boost/thread/lock_types.hpp>
1949 template <class Lockable>
1950 class upgrade_to_unique_lock
1953 typedef Lockable mutex_type;
1954 explicit upgrade_to_unique_lock(upgrade_lock<Lockable>& m_);
1955 ~upgrade_to_unique_lock();
1957 upgrade_to_unique_lock(upgrade_to_unique_lock const& other) = delete;
1958 upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> const& other) = delete;
1960 upgrade_to_unique_lock(upgrade_to_unique_lock<Lockable> && other);
1961 upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> && other);
1963 void swap(upgrade_to_unique_lock& other);
1965 explicit operator bool() const;
1966 bool owns_lock() const;
1967 mutex_type* mutex() const;
1971 __upgrade_to_unique_lock__ allows for a temporary upgrade of an __upgrade_lock__ to exclusive ownership. When constructed with a
1972 reference to an instance of __upgrade_lock__, if that instance has upgrade ownership on some __lockable_concept_type__ object, that
1973 ownership is upgraded to exclusive ownership. When the __upgrade_to_unique_lock__ instance is destroyed, the ownership of the
1974 __lockable_concept_type__ is downgraded back to ['upgrade ownership].
1978 [section:scoped_try_lock Mutex-specific class `scoped_try_lock` -- DEPRECATED]
1980 class MutexType::scoped_try_lock
1983 MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>& other);
1984 MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>& other);
1986 MutexType::scoped_try_lock();
1987 explicit MutexType::scoped_try_lock(MutexType& m);
1988 MutexType::scoped_try_lock(MutexType& m_,adopt_lock_t);
1989 MutexType::scoped_try_lock(MutexType& m_,defer_lock_t);
1990 MutexType::scoped_try_lock(MutexType& m_,try_to_lock_t);
1992 MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>&& other);
1993 MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>&& other);
1995 void swap(MutexType::scoped_try_lock&& other);
2001 MutexType* mutex() const;
2002 MutexType* release();
2004 explicit operator bool() const;
2005 bool owns_lock() const;
2008 The member typedef `scoped_try_lock` is provided for each distinct
2009 `MutexType` as a typedef to a class with the preceding definition. The
2010 semantics of each constructor and member function are identical to
2011 those of [unique_lock_link `boost::unique_lock<MutexType>`] for the same `MutexType`, except
2012 that the constructor that takes a single reference to a mutex will
2013 call [try_lock_ref_link `m.try_lock()`] rather than `m.lock()`.
2019 [section:other_mutex Other Mutex Types]
2021 [section: reverse_mutex Class template `reverse_mutex`]
2023 //#include <boost/thread/reverse_mutex.hpp>
2027 template<typename BasicLockable>
2031 typedef BasicLockable mutex_type;
2032 reverse_mutex(reverse_mutex const&) = delete;
2033 reverse_mutex& operator=(reverse_mutex const&) = delete;
2035 explicit reverse_mutex(mutex_type& m_);
2043 __reverse_mutex reverse the operations of a __BasicLockable, that unlocks the lockable when `lock()` is called and locks it when `unlock()` is called.
2050 [section:other_locks Other Lock Types - EXTENSION]
2052 [section:strict_locks Strict Locks]
2054 // #include <boost/thread/locks.hpp>
2055 // #include <boost/thread/strict_lock.hpp>
2060 template<typename Lockable>
2062 template <typename Lock>
2063 class nested_strict_lock;
2064 template <typename Lockable>
2065 struct is_strict_lock_sur_parole<strict_lock<Lockable> >;
2066 template <typename Lock>
2067 struct is_strict_lock_sur_parole<nested_strict_lock<Lock> >;
2069 #if ! defined BOOST_THREAD_NO_MAKE_STRICT_LOCK
2070 template <typename Lockable>
2071 strict_lock<Lockable> make_strict_lock(Lockable& mtx);
2073 #if ! defined BOOST_THREAD_NO_MAKE_NESTED_STRICT_LOCK
2074 template <typename Lock>
2075 nested_strict_lock<Lock> make_nested_strict_lock(Lock& lk);
2080 [section:strict_lock Class template `strict_lock`]
2082 // #include <boost/thread/locks.hpp>
2083 // #include <boost/thread/strict_lock.hpp>
2085 template<typename BasicLockable>
2089 typedef BasicLockable mutex_type;
2090 strict_lock(strict_lock const& m_) = delete;
2091 strict_lock& operator=(strict_lock const& m_) = delete;
2092 explicit strict_lock(mutex_type& m_);
2095 bool owns_lock(mutex_type const* l) const noexcept;
2098 __strict_lock is a model of __StrictLock.
2100 __strict_lock is the simplest __StrictLock: on construction it acquires ownership of the implementation of the __BasicLockable concept supplied as the constructor parameter. On destruction, the ownership is released. This provides simple RAII-style locking of a __BasicLockable object, to facilitate exception-safe locking and unlocking.
2102 [heading See also __lock_guard__]
2104 [section:constructor `strict_lock(Lockable & m)`]
2108 [[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
2110 [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
2116 [section:destructor `~strict_lock()`]
2120 [[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
2121 object passed to the constructor.]]
2123 [[Throws:] [Nothing.]]
2132 [section:nested_strict_lock Class template `nested_strict_lock`]
2134 // #include <boost/thread/locks.hpp>
2135 // #include <boost/thread/strict_lock.hpp>
2137 template<typename Lock>
2138 class nested_strict_lock
2141 typedef BasicLockable mutex_type;
2142 nested_strict_lock(nested_strict_lock const& m_) = delete;
2143 nested_strict_lock& operator=(nested_strict_lock const& m_) = delete;
2144 explicit nested_strict_lock(Lock& lk),
2145 ~nested_strict_lock() noexcept;
2147 bool owns_lock(mutex_type const* l) const noexcept;
2150 __nested_strict_lock is a model of __StrictLock.
2152 A nested strict lock is a scoped lock guard ensuring a mutex is locked on its
2153 scope, by taking ownership of a nesting lock, locking the mutex on construction if not already locked
2154 and restoring the ownership to the nesting lock on destruction.
2157 [heading See also __strict_lock, __unique_lock]
2159 [section:constructor `nested_strict_lock(Lock & lk)`]
2163 [[Requires:] [`lk.mutex() != null_ptr`.]]
2165 [[Effects:] [Stores the reference to the lock parameter `lk` and takes ownership on it.
2166 If the lock doesn't owns the mutex lock it.
2169 [[Postcondition:] [`owns_lock(lk.mutex())`.]]
2173 - lock_error when BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and lk.mutex() == null_ptr
2175 - Any exception that @c lk.lock() can throw.
2184 [section:destructor `~nested_strict_lock() noexcept`]
2188 [[Effects:] [Restores ownership to the nesting lock.]]
2195 [section:owns_lock `bool owns_lock(mutex_type const* l) const noexcept`]
2199 [[Return:] [Whether if this lock is locking that mutex.]]
2207 [section:make_strict_lock Non Member Function `make_strict_lock`]
2209 template <typename Lockable>
2210 strict_lock<Lockable> make_strict_lock(Lockable& m); // EXTENSION
2215 [[Returns:] [a strict_lock as if initialized with `{m}`.]]
2217 [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
2225 [section:make_nested_strict_lock Non Member Function `make_nested_strict_lock`]
2227 template <typename Lock>
2228 nested_strict_lock<Lock> make_nested_strict_lock(Lock& lk); // EXTENSION
2233 [[Returns:] [a nested_strict_lock as if initialized with `{lk}`.]]
2235 [[Throws:] [Any exception thrown by the call to [lock_ref_link `lk.lock()`].]]
2246 [section:lock_ptrs Locking pointers]
2248 // #include <boost/thread/synchroniezd_value.hpp>
2249 // #include <boost/thread/strict_lock_ptr.hpp>
2254 template<typename T, typename Lockable = mutex>
2255 class strict_lock_ptr;
2256 template<typename T, typename Lockable = mutex>
2257 class const_strict_lock_ptr;
2262 template<typename T, typename Lockable = mutex>
2263 class unique_lock_ptr;
2264 template<typename T, typename Lockable = mutex>
2265 class const_unique_lock_ptr;
2269 [section:const_strict_lock_ptr Class template `const_strict_lock_ptr `]
2271 // #include <boost/thread/synchroniezd_value.hpp>
2272 // #include <boost/thread/strict_lock_ptr.hpp>
2275 template <typename T, typename Lockable = mutex>
2276 class const_strict_lock_ptr
2279 typedef T value_type;
2280 typedef Lockable mutex_type;
2282 const_strict_lock_ptr(const_strict_lock_ptr const& m_) = delete;
2283 const_strict_lock_ptr& operator=(const_strict_lock_ptr const& m_) = delete;
2285 const_strict_lock_ptr(T const& val, Lockable & mtx);
2286 const_strict_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t tag);
2288 ~const_strict_lock_ptr();
2290 const T* operator->() const;
2291 const T& operator*() const;
2296 [section:constructor `const_strict_lock_ptr(T const&,Lockable&)`]
2299 const_strict_lock_ptr(T const& val, Lockable & m);
2303 [[Effects:] [Invokes [lock_ref_link `m.lock()`], stores a reference to it and to the value type `val`.]]
2305 [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
2310 [section:constructor_adopt `const_strict_lock_ptr(T const&,Lockable&,adopt_lock_t)`]
2312 const_strict_lock_ptr(T const& val, Lockable & m, adopt_lock_t tag);
2316 [[Effects:] [Stores a reference to it and to the value type `val`.]]
2318 [[Throws:] [Nothing.]]
2325 [section:destructor `~const_strict_lock_ptr()`]
2327 ~const_strict_lock_ptr();
2331 [[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
2332 object passed to the constructor.]]
2334 [[Throws:] [Nothing.]]
2340 [section:indir `operator->() const`]
2342 const T* operator->() const;
2347 [[Return:] [return a constant pointer to the protected value.]]
2349 [[Throws:] [Nothing.]]
2355 [section:deref `operator*() const`]
2357 const T& operator*() const;
2362 [[Return:] [return a constant reference to the protected value.]]
2364 [[Throws:] [Nothing.]]
2371 [endsect] [/ const_strict_lock_ptr ]
2373 [section:strict_lock_ptr Class template `strict_lock_ptr`]
2375 // #include <boost/thread/synchroniezd_value.hpp>
2376 // #include <boost/thread/strict_lock_ptr.hpp>
2378 template <typename T, typename Lockable = mutex>
2379 class strict_lock_ptr : public const_strict_lock_ptr<T,Lockable>
2382 strict_lock_ptr(strict_lock_ptr const& m_) = delete;
2383 strict_lock_ptr& operator=(strict_lock_ptr const& m_) = delete;
2385 strict_lock_ptr(T & val, Lockable & mtx);
2386 strict_lock_ptr(T & val, Lockable & mtx, adopt_lock_t tag);
2395 [section:constructor `strict_lock_ptr(T const&,Lockable&)`]
2398 strict_lock_ptr(T const& val, Lockable & m);
2402 [[Effects:] [Invokes [lock_ref_link `m.lock()`], stores a reference to it and to the value type `val`.]]
2404 [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
2409 [section:constructor_adopt `strict_lock_ptr(T const&,Lockable&,adopt_lock_t)`]
2411 strict_lock_ptr(T const& val, Lockable & m, adopt_lock_t tag);
2415 [[Effects:] [Stores a reference to it and to the value type `val`.]]
2417 [[Throws:] [Nothing.]]
2424 [section:destructor `~strict_lock_ptr()`]
2426 ~ strict_lock_ptr();
2430 [[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
2431 object passed to the constructor.]]
2433 [[Throws:] [Nothing.]]
2439 [section:indir `operator->()`]
2446 [[Return:] [return a pointer to the protected value.]]
2448 [[Throws:] [Nothing.]]
2454 [section:deref `operator*()`]
2461 [[Return:] [return a reference to the protected value.]]
2463 [[Throws:] [Nothing.]]
2470 [endsect] [/ strict_lock_ptr ]
2472 [endsect] [/ lock_ptrs ]
2475 [section Externally Locked]
2477 // #include <boost/thread/externally_locked.hpp>
2478 template <class T, typename MutexType = boost::mutex>
2479 class externally_locked;
2480 template <class T, typename MutexType>
2481 class externally_locked<T&, MutexType>;
2483 template <typename T, typename MutexType>
2484 void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs);
2486 [section:externally_locked Template Class `externally_locked`]
2488 // #include <boost/thread/externally_locked.hpp>
2490 template <class T, typename MutexType>
2491 class externally_locked
2493 //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
2494 BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
2497 typedef MutexType mutex_type;
2499 externally_locked(mutex_type& mtx, const T& obj);
2500 externally_locked(mutex_type& mtx,T&& obj);
2501 explicit externally_locked(mutex_type& mtx);
2502 externally_locked(externally_locked const& rhs);
2503 externally_locked(externally_locked&& rhs);
2504 externally_locked& operator=(externally_locked const& rhs);
2505 externally_locked& operator=(externally_locked&& rhs);
2508 T& get(strict_lock<mutex_type>& lk);
2509 const T& get(strict_lock<mutex_type>& lk) const;
2511 template <class Lock>
2512 T& get(nested_strict_lock<Lock>& lk);
2513 template <class Lock>
2514 const T& get(nested_strict_lock<Lock>& lk) const;
2516 template <class Lock>
2518 template <class Lock>
2519 T const& get(Lock& lk) const;
2521 mutex_type* mutex() const noexcept;
2527 void swap(externally_locked&);
2530 `externally_locked` is a model of __Lockable, it cloaks an object of type `T`, and actually provides full
2531 access to that object through the get and set member functions, provided you
2532 pass a reference to a strict lock object.
2534 Only the specificities respect to __Lockable are described here.
2536 [///////////////////////////////]
2537 [section:constructor1 `externally_locked(mutex_type&, const T&)`]
2539 externally_locked(mutex_type& mtx, const T& obj);
2543 [[Requires:] [T is a model of CopyConstructible.]]
2545 [[Effects:] [Constructs an externally locked object copying the cloaked type.]]
2547 [[Throws:] [Any exception thrown by the call to `T(obj)`.]]
2552 [///////////////////////////////]
2553 [section:constructor2 `externally_locked(mutex_type&, T&&)`]
2555 externally_locked(mutex_type& mtx,T&& obj);
2559 [[Requires:] [T is a model of Movable.]]
2561 [[Effects:] [Constructs an externally locked object by moving the cloaked type.]]
2563 [[Throws:] [Any exception thrown by the call to `T(obj)`.]]
2568 [///////////////////////////////]
2569 [section:constructor3 `externally_locked(mutex_type&)`]
2571 externally_locked(mutex_type& mtx);
2575 [[Requires:] [T is a model of DefaultConstructible.]]
2577 [[Effects:] [Constructs an externally locked object by default constructing the cloaked type.]]
2579 [[Throws:] [Any exception thrown by the call to `T()`.]]
2584 [///////////////////////////////]
2585 [section:constructor4 `externally_locked(externally_locked&&)`]
2587 externally_locked(externally_locked&& rhs);
2591 [[Requires:] [T is a model of Movable.]]
2593 [[Effects:] [Move constructs an externally locked object by moving the cloaked type and copying the mutex reference ]]
2595 [[Throws:] [Any exception thrown by the call to `T(T&&)`.]]
2600 [///////////////////////////////]
2601 [section:constructor5 `externally_locked(externally_locked&)`]
2603 externally_locked(externally_locked& rhs);
2607 [[Requires:] [T is a model of Copyable.]]
2609 [[Effects:] [Copy constructs an externally locked object by copying the cloaked type and copying the mutex reference ]]
2611 [[Throws:] [Any exception thrown by the call to `T(T&)`.]]
2616 [///////////////////////////////]
2617 [section:assign4 `externally_locked(externally_locked&&)`]
2619 externally_locked& operator=(externally_locked&& rhs);
2623 [[Requires:] [T is a model of Movable.]]
2625 [[Effects:] [Move assigns an externally locked object by moving the cloaked type and copying the mutex reference ]]
2627 [[Throws:] [Any exception thrown by the call to `T::operator=(T&&)`.]]
2632 [///////////////////////////////]
2633 [section:assign5 `externally_locked(externally_locked&)`]
2635 externally_locked& operator=(externally_locked const& rhs);
2639 [[Requires:] [T is a model of Copyable.]]
2641 [[Effects:] [Copy assigns an externally locked object by copying the cloaked type and copying the mutex reference ]]
2643 [[Throws:] [Any exception thrown by the call to `T::operator=(T&)`.]]
2649 [///////////////////////////////]
2650 [section:get1 `get(strict_lock<mutex_type>&)`]
2652 T& get(strict_lock<mutex_type>& lk);
2653 const T& get(strict_lock<mutex_type>& lk) const;
2657 [[Requires:] [The `lk` parameter must be locking the associated mutex.]]
2659 [[Returns:] [A reference to the cloaked object ]]
2661 [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
2666 [///////////////////////////////]
2667 [section:get2 `get(nested_strict_lock<Lock>&)`]
2669 template <class Lock>
2670 T& get(nested_strict_lock<Lock>& lk);
2671 template <class Lock>
2672 const T& get(nested_strict_lock<Lock>& lk) const;
2676 [[Requires:] [`is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
2678 [[Returns:] [A reference to the cloaked object ]]
2680 [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
2686 [///////////////////////////////]
2687 [section:get3 `get(Lock&)`]
2689 template <class Lock>
2691 template <class Lock>
2692 T const& get(Lock& lk) const;
2696 [[Requires:] [`Lock` is a model of __StrictLock, `is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
2698 [[Returns:] [A reference to the cloaked object ]]
2700 [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
2707 [section:externally_locked_ref Template Class `externally_locked<T&>`]
2709 // #include <boost/thread/externally_locked.hpp>
2711 template <class T, typename MutexType>
2712 class externally_locked<T&, MutexType>
2714 //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
2715 BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
2718 typedef MutexType mutex_type;
2720 externally_locked(mutex_type& mtx, T& obj);
2721 explicit externally_locked(mutex_type& mtx);
2722 externally_locked(externally_locked const& rhs) noexcept;
2723 externally_locked(externally_locked&& rhs) noexcept;
2724 externally_locked& operator=(externally_locked const& rhs) noexcept;
2725 externally_locked& operator=(externally_locked&& rhs) noexcept;
2728 T& get(strict_lock<mutex_type>& lk);
2729 const T& get(strict_lock<mutex_type>& lk) const;
2731 template <class Lock>
2732 T& get(nested_strict_lock<Lock>& lk);
2733 template <class Lock>
2734 const T& get(nested_strict_lock<Lock>& lk) const;
2736 template <class Lock>
2738 template <class Lock>
2739 T const& get(Lock& lk) const;
2741 mutex_type* mutex() const noexcept;
2747 void swap(externally_locked&) noexcept;
2750 `externally_locked` is a model of __Lockable, it cloaks an object of type `T`, and actually provides full
2751 access to that object through the get and set member functions, provided you
2752 pass a reference to a strict lock object.
2754 Only the specificities respect to __Lockable are described here.
2756 [///////////////////////////////]
2757 [section:constructor1 `externally_locked<T&>(mutex_type&, T&)`]
2759 externally_locked<T&>(mutex_type& mtx, T& obj) noexcept;
2764 [[Effects:] [Constructs an externally locked object copying the cloaked reference.]]
2769 [///////////////////////////////]
2770 [section:constructor4 `externally_locked<T&>(externally_locked&&)`]
2772 externally_locked(externally_locked&& rhs) noexcept;
2776 [[Effects:] [Moves an externally locked object by moving the cloaked type and copying the mutex reference ]]
2782 [///////////////////////////////]
2783 [section:assign4 `externally_locked(externally_locked&&)`]
2785 externally_locked& operator=(externally_locked&& rhs);
2789 [[Effects:] [Move assigns an externally locked object by copying the cloaked reference and copying the mutex reference ]]
2794 [///////////////////////////////]
2795 [section:assign5 `externally_locked(externally_locked&)`]
2797 externally_locked& operator=(externally_locked const& rhs);
2801 [[Requires:] [T is a model of Copyable.]]
2803 [[Effects:] [Copy assigns an externally locked object by copying the cloaked reference and copying the mutex reference ]]
2805 [[Throws:] [Any exception thrown by the call to `T::operator=(T&)`.]]
2811 [///////////////////////////////]
2812 [section:get1 `get(strict_lock<mutex_type>&)`]
2814 T& get(strict_lock<mutex_type>& lk);
2815 const T& get(strict_lock<mutex_type>& lk) const;
2819 [[Requires:] [The `lk` parameter must be locking the associated mutex.]]
2821 [[Returns:] [A reference to the cloaked object ]]
2823 [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
2828 [///////////////////////////////]
2829 [section:get2 `get(nested_strict_lock<Lock>&)`]
2831 template <class Lock>
2832 T& get(nested_strict_lock<Lock>& lk);
2833 template <class Lock>
2834 const T& get(nested_strict_lock<Lock>& lk) const;
2838 [[Requires:] [`is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
2840 [[Returns:] [A reference to the cloaked object ]]
2842 [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
2848 [///////////////////////////////]
2849 [section:get3 `get(Lock&)`]
2851 template <class Lock>
2853 template <class Lock>
2854 T const& get(Lock& lk) const;
2858 [[Requires:] [`Lock` is a model of __StrictLock, `is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
2860 [[Returns:] [A reference to the cloaked object ]]
2862 [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
2871 [///////////////////////////////]
2872 [section:swap `swap(externally_locked&, externally_locked&)`]
2874 template <typename T, typename MutexType>
2875 void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs)
2882 [section:shared_lock_guard Class template `shared_lock_guard`]
2884 // #include <boost/thread/shared_lock_guard.hpp>
2887 template<typename SharedLockable>
2888 class shared_lock_guard
2891 shared_lock_guard(shared_lock_guard const&) = delete;
2892 shared_lock_guard& operator=(shared_lock_guard const&) = delete;
2894 explicit shared_lock_guard(SharedLockable& m_);
2895 shared_lock_guard(SharedLockable& m_,boost::adopt_lock_t);
2897 ~shared_lock_guard();
2901 __shared_lock_guard is very simple: on construction it
2902 acquires shared ownership of the implementation of the __shared_lockable_concept__ supplied as
2903 the constructor parameter. On destruction, the ownership is released. This
2904 provides simple RAII-style locking of a __shared_lockable_concept_type__ object, to facilitate exception-safe
2905 shared locking and unlocking.
2906 In addition, the `__shared_lock_guard_constructor_adopt(SharedLockable &m, boost::adopt_lock_t)` constructor allows the __shared_lock_guard object to
2907 take shared ownership of a lock already held by the current thread.
2909 [section:constructor `shared_lock_guard(SharedLockable & m)`]
2913 [[Effects:] [Stores a reference to `m`. Invokes `m.__lock_shared()`.]]
2915 [[Throws:] [Any exception thrown by the call to `m.__lock_shared()`.]]
2921 [section:constructor_adopt `shared_lock_guard(SharedLockable & m,boost::adopt_lock_t)`]
2925 [[Precondition:] [The current thread owns a lock on `m` equivalent to one
2926 obtained by a call to `m.__lock_shared()`.]]
2928 [[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of
2931 [[Throws:] [Nothing.]]
2937 [section:destructor `~shared_lock_guard()`]
2941 [[Effects:] [Invokes `m.__unlock_shared()` on the __shared_lockable_concept_type__ object passed to the constructor.]]
2943 [[Throws:] [Nothing.]]
2951 [section:reverse_lock Class template `reverse_lock`]
2953 // #include <boost/thread/reverse_lock.hpp>
2957 template<typename Lock>
2961 reverse_lock(reverse_lock const&) = delete;
2962 reverse_lock& operator=(reverse_lock const&) = delete;
2964 explicit reverse_lock(Lock& m_);
2969 __reverse_lock reverse the operations of a lock: it provide for RAII-style, that unlocks the lock at construction time and lock it at destruction time. In addition, it transfer ownership temporarily, so that the mutex can not be locked using the Lock.
2971 An instance of __reverse_lock doesn't ['own] the lock never.
2974 [section:constructor `reverse_lock(Lock & m)`]
2978 [[Effects:] [Stores a reference to `m`. Invokes `m.__unlock()` if `m` owns his lock and then stores the mutex by calling `m.release()`.]]
2980 [[Postcondition:] [`!m.__owns_lock() && m.mutex()==0`.]]
2982 [[Throws:] [Any exception thrown by the call to `m.__unlock()`.]]
2989 [section:destructor `~reverse_lock()`]
2993 [[Effects:] [Let be mtx the stored mutex*. If not 0 Invokes `mtx->__lock()` and gives again the `mtx` to the `Lock` using the `adopt_lock_t` overload.]]
2995 [[Throws:] [Any exception thrown by `mtx->__lock()`.]]
2997 [[Remarks:] [Note that if `mtx->__lock()` throws an exception while unwinding the program will terminate, so don't use reverse_lock if an exception can be thrown.]]
3004 [endsect] [/ reverse_lock<>]
3009 [section:lock_functions Lock functions]
3011 [section:lock_multiple Non-member function `lock(Lockable1,Lockable2,...)`]
3013 // #include <boost/thread/locks.hpp>
3014 // #include <boost/thread/lock_algorithms.hpp>
3018 template<typename Lockable1,typename Lockable2>
3019 void lock(Lockable1& l1,Lockable2& l2);
3021 template<typename Lockable1,typename Lockable2,typename Lockable3>
3022 void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);
3024 template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
3025 void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);
3027 template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
3028 void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);
3034 [[Effects:] [Locks the __lockable_concept_type__ objects supplied as
3035 arguments in an unspecified and indeterminate order in a way that
3036 avoids deadlock. It is safe to call this function concurrently from
3037 multiple threads with the same mutexes (or other lockable objects) in
3038 different orders without risk of deadlock. If any of the __lock_ref__
3039 or __try_lock_ref__ operations on the supplied
3040 __lockable_concept_type__ objects throws an exception any locks
3041 acquired by the function will be released before the function exits.]]
3043 [[Throws:] [Any exceptions thrown by calling __lock_ref__ or
3044 __try_lock_ref__ on the supplied __lockable_concept_type__ objects.]]
3046 [[Postcondition:] [All the supplied __lockable_concept_type__ objects
3047 are locked by the calling thread.]]
3053 [section:lock_range Non-member function `lock(begin,end)` // EXTENSION]
3055 template<typename ForwardIterator>
3056 void lock(ForwardIterator begin,ForwardIterator end);
3060 [[Preconditions:] [The `value_type` of `ForwardIterator` must implement the __lockable_concept__]]
3062 [[Effects:] [Locks all the __lockable_concept_type__ objects in the
3063 supplied range in an unspecified and indeterminate order in a way that
3064 avoids deadlock. It is safe to call this function concurrently from
3065 multiple threads with the same mutexes (or other lockable objects) in
3066 different orders without risk of deadlock. If any of the __lock_ref__
3067 or __try_lock_ref__ operations on the __lockable_concept_type__
3068 objects in the supplied range throws an exception any locks acquired
3069 by the function will be released before the function exits.]]
3071 [[Throws:] [Any exceptions thrown by calling __lock_ref__ or
3072 __try_lock_ref__ on the supplied __lockable_concept_type__ objects.]]
3074 [[Postcondition:] [All the __lockable_concept_type__ objects in the
3075 supplied range are locked by the calling thread.]]
3081 [section:try_lock_multiple Non-member function `try_lock(Lockable1,Lockable2,...)`]
3083 template<typename Lockable1,typename Lockable2>
3084 int try_lock(Lockable1& l1,Lockable2& l2);
3086 template<typename Lockable1,typename Lockable2,typename Lockable3>
3087 int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);
3089 template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
3090 int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);
3092 template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
3093 int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);
3097 [[Effects:] [Calls __try_lock_ref__ on each of the
3098 __lockable_concept_type__ objects supplied as arguments. If any of the
3099 calls to __try_lock_ref__ returns `false` then all locks acquired are
3100 released and the zero-based index of the failed lock is returned.
3102 If any of the __try_lock_ref__ operations on the supplied
3103 __lockable_concept_type__ objects throws an exception any locks
3104 acquired by the function will be released before the function exits.]]
3106 [[Returns:] [`-1` if all the supplied __lockable_concept_type__ objects
3107 are now locked by the calling thread, the zero-based index of the
3108 object which could not be locked otherwise.]]
3110 [[Throws:] [Any exceptions thrown by calling __try_lock_ref__ on the
3111 supplied __lockable_concept_type__ objects.]]
3113 [[Postcondition:] [If the function returns `-1`, all the supplied
3114 __lockable_concept_type__ objects are locked by the calling
3115 thread. Otherwise any locks acquired by this function will have been
3122 [section:try_lock_range Non-member function `try_lock(begin,end)` // EXTENSION]
3124 template<typename ForwardIterator>
3125 ForwardIterator try_lock(ForwardIterator begin,ForwardIterator end);
3129 [[Preconditions:] [The `value_type` of `ForwardIterator` must implement the __lockable_concept__]]
3131 [[Effects:] [Calls __try_lock_ref__ on each of the
3132 __lockable_concept_type__ objects in the supplied range. If any of the
3133 calls to __try_lock_ref__ returns `false` then all locks acquired are
3134 released and an iterator referencing the failed lock is returned.
3136 If any of the __try_lock_ref__ operations on the supplied
3137 __lockable_concept_type__ objects throws an exception any locks
3138 acquired by the function will be released before the function exits.]]
3140 [[Returns:] [`end` if all the supplied __lockable_concept_type__
3141 objects are now locked by the calling thread, an iterator referencing
3142 the object which could not be locked otherwise.]]
3144 [[Throws:] [Any exceptions thrown by calling __try_lock_ref__ on the
3145 supplied __lockable_concept_type__ objects.]]
3147 [[Postcondition:] [If the function returns `end` then all the
3148 __lockable_concept_type__ objects in the supplied range are locked by
3149 the calling thread, otherwise all locks acquired by the function have
3157 [section:lock_factories Lock Factories - EXTENSION]
3162 template <typename Lockable>
3163 unique_lock<Lockable> make_unique_lock(Lockable& mtx); // EXTENSION
3165 template <typename Lockable>
3166 unique_lock<Lockable> make_unique_lock(Lockable& mtx, adopt_lock_t); // EXTENSION
3167 template <typename Lockable>
3168 unique_lock<Lockable> make_unique_lock(Lockable& mtx, defer_lock_t); // EXTENSION
3169 template <typename Lockable>
3170 unique_lock<Lockable> make_unique_lock(Lockable& mtx, try_to_lock_t); // EXTENSION
3172 #if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
3173 template <typename ...Lockable>
3174 std::tuple<unique_lock<Lockable> ...> make_unique_locks(Lockable& ...mtx); // EXTENSION
3178 [section:make_unique_lock Non Member Function `make_unique_lock(Lockable&)`]
3180 template <typename Lockable>
3181 unique_lock<Lockable> make_unique_lock(Lockable& mtx); // EXTENSION
3186 [[Returns:] [a __unique_lock as if initialized with `unique_lock<Lockable>(mtx)`.]]
3188 [[Throws:] [Any exception thrown by the call to `__unique_lock<Lockable>(mtx)`.]]
3194 [section:make_unique_lock_t Non Member Function `make_unique_lock(Lockable&,tag)`]
3196 template <typename Lockable>
3197 unique_lock<Lockable> make_unique_lock(Lockable& mtx, adopt_lock_t tag); // EXTENSION
3199 template <typename Lockable>
3200 unique_lock<Lockable> make_unique_lock(Lockable& mtx, defer_lock_t tag); // EXTENSION
3202 template <typename Lockable>
3203 unique_lock<Lockable> make_unique_lock(Lockable& mtx, try_to_lock_t tag); // EXTENSION
3208 [[Returns:] [a __unique_lock as if initialized with `unique_lock<Lockable>(mtx, tag)`.]]
3210 [[Throws:] [Any exception thrown by the call to `__unique_lock<Lockable>(mtx, tag)`.]]
3217 [section:make_unique_locks Non Member Function `make_unique_locks(Lockable& ...)`]
3219 template <typename ...Lockable>
3220 std::tuple<unique_lock<Lockable> ...> make_unique_locks(Lockable& ...mtx); // EXTENSION
3224 [[Effect:] [Locks all the mutexes.]]
3226 [[Returns:] [a std::tuple of unique __unique_lock owning each one of the mutex.]]
3228 [[Throws:] [Any exception thrown by `boost::lock(mtx...)`.]]