diff options
Diffstat (limited to 'libs/thread/doc/mutex_concepts.qbk')
-rw-r--r-- | libs/thread/doc/mutex_concepts.qbk | 1140 |
1 files changed, 976 insertions, 164 deletions
diff --git a/libs/thread/doc/mutex_concepts.qbk b/libs/thread/doc/mutex_concepts.qbk index dd3aba79d4..aa33179bb9 100644 --- a/libs/thread/doc/mutex_concepts.qbk +++ b/libs/thread/doc/mutex_concepts.qbk @@ -1,5 +1,6 @@ [/ (C) Copyright 2007-8 Anthony Williams. + (C) Copyright 2011-12 Vicente J. Botet Escriba. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). @@ -17,58 +18,86 @@ __boost_thread__ supports four basic concepts for lockable objects: __lockable_c __shared_lockable_concept_type__ and __upgrade_lockable_concept_type__. Each mutex type implements one or more of these concepts, as do the various lock types. -[section:lockable `Lockable` Concept] +[section:basic_lockable `BasicLockable` Concept] -The __lockable_concept__ models exclusive ownership. A type that implements the __lockable_concept__ shall provide the following -member functions: +The __BasicLockable concept models exclusive ownership. +A type `L` meets the __BasicLockable requiremets if the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`): -* [lock_ref_link `void lock();`] -* [try_lock_ref_link `bool try_lock();`] -* [unlock_ref_link `void unlock();`] +* `m.__lock();` +* `m.__unlock();` -Lock ownership acquired through a call to __lock_ref__ or __try_lock_ref__ must be released through a call to __unlock_ref__. +Lock ownership acquired through a call to __lock_ref__ must be released through a call to __unlock_ref__. -[section:lock `void lock()`] +[section:lock `m.lock();`] [variablelist [[Effects:] [The current thread blocks until ownership can be obtained for the current thread.]] -[[Postcondition:] [The current thread owns `*this`.]] +[[Postcondition:] [The current thread owns `m`.]] + +[[Return type:] [`void`.]] [[Throws:] [__thread_resource_error__ if an error occurs.]] +[[Error Conditions:] [ + +[*operation_not_permitted]: if the thread does not have the privilege to perform the operation. + +[*resource_deadlock_would_occur]: if the implementation detects that a deadlock would occur. + +[*device_or_resource_busy]: if the mutex is already locked and blocking is not possible. + +]] + +[[Thread safety:] [If an exception is thrown then a lock shall not have been acquired for the current thread.]] + ] [endsect] -[section:try_lock `bool try_lock()`] +[section:unlock `m.unlock();`] [variablelist -[[Effects:] [Attempt to obtain ownership for the current thread without blocking.]] +[[Precondition:] [The current thread owns `m`.]] -[[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]] +[[Effects:] [Releases ownership by the current thread.]] -[[Postcondition:] [If the call returns `true`, the current thread owns the `*this`.]] +[[Return type:] [`void`.]] -[[Throws:] [__thread_resource_error__ if an error occurs.]] +[[Postcondition:] [The current thread no longer owns `m`.]] +[[Throws:] [Nothing.]] ] [endsect] -[section:unlock `void unlock()`] + +[endsect] +[section:lockable `Lockable` Concept] + +A type `L` meets the __Lockable requirements if it meets the __BasicLocable requirements and the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`): + +* `m.__try_lock()` + +Lock ownership acquired through a call to __try_lock_ref__ must be released through a call to __unlock_ref__. + +[section:try_lock `m.try_lock()`] [variablelist -[[Precondition:] [The current thread owns `*this`.]] +[[Effects:] [Attempt to obtain ownership for the current thread without blocking.]] -[[Effects:] [Releases ownership by the current thread.]] +[[Return type:] [`bool`.]] -[[Postcondition:] [The current thread no longer owns `*this`.]] +[[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread owns the `m`.]] + +[[Throws:] [Nothing.]] -[[Throws:] [Nothing]] ] [endsect] + [endsect] [section:timed_lockable `TimedLockable` Concept] @@ -76,16 +105,62 @@ Lock ownership acquired through a call to __lock_ref__ or __try_lock_ref__ must The __timed_lockable_concept__ refines the __lockable_concept__ to add support for timeouts when trying to acquire the lock. -A type that implements the __timed_lockable_concept__ shall meet the requirements -of the __lockable_concept__. In addition, the following member functions must be -provided: +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. + +[*Variables:] + +* `m` denotes a value of type `L`, +* `rel_time` denotes a value of an instantiation of `chrono::duration`, and +* `abs_time` denotes a value of an instantiation of `chrono::time_point`: + +[*Expressions:] + +* `m.__try_lock_for(rel_time)` +* `m.__try_lock_until(abs_time)` + +Lock ownership acquired through a call to __try_lock_for or __try_lock_until must be released through a call to __unlock. + +[section:try_lock_until `m.try_lock_until(abs_time)`] -* [timed_lock_ref_link `bool timed_lock(boost::system_time const& abs_time);`] -* [timed_lock_duration_ref_link `template<typename DurationType> bool timed_lock(DurationType const& rel_time);`] +[variablelist + +[[Effects:] [Attempt to obtain ownership for the current thread. Blocks until ownership can be obtained, or the specified time is +reached. If the specified time has already passed, behaves as __try_lock_ref__.]] + +[[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread owns `m`.]] + +[[Throws:] [Nothing.]] +] +[endsect] + +[section:try_lock_for `m.try_lock_for(rel_time)`] + +[variablelist + +[[Effects:] [As-if `__try_lock_until(chrono::steady_clock::now() + rel_time)`.]] + +] +[endsect] + +[heading Deprecated V3.0.0] + +The following expressions were required on version 2, but are now deprecated. + +[*Variables:] + +* `rel_time` denotes a value of an instantiation of an unspecified `DurationType` arithmetic compatible with `boost::system_time`, and +* `abs_time` denotes a value of an instantiation of `boost::system_time`: + +[*Expressions:] + +* `m.__timed_lock_duration(rel_time)` +* `m.__timed_lock(abs_time)` Lock ownership acquired through a call to __timed_lock_ref__ must be released through a call to __unlock_ref__. -[section:timed_lock `bool timed_lock(boost::system_time const& abs_time)`] +[section:timed_lock `m.timed_lock(abs_time)`] [variablelist @@ -94,14 +169,13 @@ reached. If the specified time has already passed, behaves as __try_lock_ref__.] [[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]] -[[Postcondition:] [If the call returns `true`, the current thread owns `*this`.]] +[[Postcondition:] [If the call returns `true`, the current thread owns `m`.]] [[Throws:] [__thread_resource_error__ if an error occurs.]] ] [endsect] -[section:timed_lock_duration `template<typename DurationType> bool -timed_lock(DurationType const& rel_time)`] +[section:timed_lock_duration `m.timed_lock(rel_time)`] [variablelist @@ -111,6 +185,7 @@ timed_lock(DurationType const& rel_time)`] ] [endsect] + [endsect] [section:shared_lockable `SharedLockable` Concept] @@ -122,32 +197,38 @@ exclusive ownership, and if any thread does have exclusive ownership, no other t can have shared or exclusive ownership. Alternatively, many threads may have shared ownership. -For a type to implement the __shared_lockable_concept__, as well as meeting the -requirements of the __timed_lockable_concept__, it must also provide the following -member functions: +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. + +[*Variables:] -* [lock_shared_ref_link `void lock_shared();`] -* [try_lock_shared_ref_link `bool try_lock_shared();`] -* [unlock_shared_ref_link `bool unlock_shared();`] -* [timed_lock_shared_ref_link `bool timed_lock_shared(boost::system_time const& abs_time);`] +* `m` denotes a value of type `L`, +* `rel_time` denotes a value of an instantiation of `chrono::duration`, and +* `abs_time` denotes a value of an instantiation of `chrono::time_point`: -Lock ownership acquired through a call to __lock_shared_ref__, __try_lock_shared_ref__ or __timed_lock_shared_ref__ must be released -through a call to __unlock_shared_ref__. +[*Expressions:] -[section:lock_shared `void lock_shared()`] +* `m.__lock_shared();` +* `m.__try_lock_shared()` +* `m.__try_lock_shared_for(rel_time)` +* `m.__try_lock_shared_until(abs_time)` +* `m.__unlock_shared();` + +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__. + +[section:lock_shared `m.lock_shared()`] [variablelist [[Effects:] [The current thread blocks until shared ownership can be obtained for the current thread.]] -[[Postcondition:] [The current thread has shared ownership of `*this`.]] +[[Postcondition:] [The current thread has shared ownership of `m`.]] [[Throws:] [__thread_resource_error__ if an error occurs.]] ] [endsect] -[section:try_lock_shared `bool try_lock_shared()`] +[section:try_lock_shared `m.try_lock_shared()`] [variablelist @@ -155,14 +236,31 @@ through a call to __unlock_shared_ref__. [[Returns:] [`true` if shared ownership was obtained for the current thread, `false` otherwise.]] -[[Postcondition:] [If the call returns `true`, the current thread has shared ownership of `*this`.]] +[[Postcondition:] [If the call returns `true`, the current thread has shared ownership of `m`.]] [[Throws:] [__thread_resource_error__ if an error occurs.]] ] [endsect] -[section:timed_lock_shared `bool timed_lock_shared(boost::system_time const& abs_time)`] +[section:try_lock_shared_for `m.try_lock_shared_for(rel_time)`] + +[variablelist + +[[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the +specified duration is elapsed. If the specified duration is already elapsed, behaves as __try_lock_shared_ref__.]] + +[[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has shared +ownership of `m`.]] + +[[Throws:] [__thread_resource_error__ if an error occurs.]] + +] +[endsect] + +[section:try_lock_shared_until `m.try_lock_shared_until(abs_time))`] [variablelist @@ -172,28 +270,60 @@ specified time is reached. If the specified time has already passed, behaves as [[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]] [[Postcondition:] [If the call returns `true`, the current thread has shared -ownership of `*this`.]] +ownership of `m`.]] [[Throws:] [__thread_resource_error__ if an error occurs.]] ] [endsect] -[section:unlock_shared `void unlock_shared()`] +[section:unlock_shared `m.unlock_shared()`] [variablelist -[[Precondition:] [The current thread has shared ownership of `*this`.]] +[[Precondition:] [The current thread has shared ownership of `m`.]] -[[Effects:] [Releases shared ownership of `*this` by the current thread.]] +[[Effects:] [Releases shared ownership of `m` by the current thread.]] -[[Postcondition:] [The current thread no longer has shared ownership of `*this`.]] +[[Postcondition:] [The current thread no longer has shared ownership of `m`.]] [[Throws:] [Nothing]] ] [endsect] +[heading Deprecated V3] + +The following expressions were required on version 1, but are now deprecated. + +[*Variables:] + +* `abs_time` denotes a value of an instantiation of `boost::system_time`: + +[*Expressions:] + +* `m.timed_lock_shared(abs_time);` + +Lock ownership acquired through a call to __timed_lock_shared_ref__ must be released through a call to __unlock_shared_ref__. + +[section:timed_lock_shared `m.timed_lock_shared(abs_time)`] + +[variablelist + +[[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the +specified time is reached. If the specified time has already passed, behaves as __try_lock_shared_ref__.]] + +[[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has shared +ownership of `m`.]] + +[[Throws:] [__thread_resource_error__ if an error occurs.]] + +] +[endsect] + + [endsect] @@ -213,91 +343,441 @@ Ownership can also be ['downgraded] as well as ['upgraded]: exclusive ownership __upgrade_lockable_concept__ can be downgraded to upgradable ownership or shared ownership, and upgradable ownership can be downgraded to plain shared ownership. -For a type to implement the __upgrade_lockable_concept__, as well as meeting the -requirements of the __shared_lockable_concept__, it must also provide the following -member functions: +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. + +[*Variables:] + +* `m` denotes a value of type `L`, +* `rel_time` denotes a value of an instantiation of `chrono::duration`, and +* `abs_time` denotes a value of an instantiation of `chrono::time_point`: + +[*Expressions:] + +* `m.__lock_upgrade();` +* `m.__unlock_upgrade()` +* `m.__try_lock_upgrade()` +* `m.__try_lock_upgrade_for(rel_time)` +* `m.__try_lock_upgrade_until(abs_time)` +* `m.__unlock_and_lock_shared()` +* `m.__unlock_and_lock_upgrade();` +* `m.__unlock_upgrade_and_lock();`] +* `m.__try_unlock_upgrade_and_lock()` +* `m.__try_unlock_upgrade_and_lock_for(rel_time)` +* `m.__try_unlock_upgrade_and_lock_until(abs_time)` +* `m.__unlock_upgrade_and_lock_shared();` + + +If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION is defined the following expressions are also required: + +* `m.__try_unlock_shared_and_lock();` +* `m.__try_unlock_shared_and_lock_for(rel_time);` +* `m.__try_unlock_shared_and_lock_until(abs_time);` +* `m.__try_unlock_shared_and_lock_upgrade();` +* `m.__try_unlock_shared_and_lock_upgrade_for(rel_time);` +* `m.__try_unlock_shared_and_lock_upgrade_until(abs_time);` -* [lock_upgrade_ref_link `void lock_upgrade();`] -* [unlock_upgrade_ref_link `bool unlock_upgrade();`] -* [unlock_upgrade_and_lock_ref_link `void unlock_upgrade_and_lock();`] -* [unlock_and_lock_upgrade_ref_link `void unlock_and_lock_upgrade();`] -* [unlock_upgrade_and_lock_shared_ref_link `void unlock_upgrade_and_lock_shared();`] Lock ownership acquired through a call to __lock_upgrade_ref__ must be released through a call to __unlock_upgrade_ref__. If the ownership type is changed through a call to one of the `unlock_xxx_and_lock_yyy()` functions, ownership must be released through a call to the unlock function corresponding to the new level of ownership. -[section:lock_upgrade `void lock_upgrade()`] +[section:lock_upgrade `m.lock_upgrade()`] [variablelist +[[Precondition:] [The calling thread has no ownership of the mutex. ]] + [[Effects:] [The current thread blocks until upgrade ownership can be obtained for the current thread.]] -[[Postcondition:] [The current thread has upgrade ownership of `*this`.]] +[[Postcondition:] [The current thread has upgrade ownership of `m`.]] + +[[Synchronization:] [Prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]] [[Throws:] [__thread_resource_error__ if an error occurs.]] ] [endsect] -[section:unlock_upgrade `void unlock_upgrade()`] +[section:unlock_upgrade `m.unlock_upgrade()`] [variablelist -[[Precondition:] [The current thread has upgrade ownership of `*this`.]] +[[Precondition:] [The current thread has upgrade ownership of `m`.]] -[[Effects:] [Releases upgrade ownership of `*this` by the current thread.]] +[[Effects:] [Releases upgrade ownership of `m` by the current thread.]] -[[Postcondition:] [The current thread no longer has upgrade ownership of `*this`.]] +[[Postcondition:] [The current thread no longer has upgrade ownership of `m`.]] +[[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership on the same object.]] + [[Throws:] [Nothing]] ] [endsect] -[section:unlock_upgrade_and_lock `void unlock_upgrade_and_lock()`] +[section:try_lock_upgrade `m.try_lock_upgrade()`] [variablelist -[[Precondition:] [The current thread has upgrade ownership of `*this`.]] +[[Precondition:] [The calling thread has no ownership of the mutex. ]] -[[Effects:] [Atomically releases upgrade ownership of `*this` by the current thread and acquires exclusive ownership of `*this`. If -any other threads have shared ownership, blocks until exclusive ownership can be acquired.]] +[[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.]] + +[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]] -[[Postcondition:] [The current thread has exclusive ownership of `*this`.]] +[[Synchronization:] [If `__try_lock_upgrade()` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]] [[Throws:] [Nothing]] ] [endsect] -[section:unlock_upgrade_and_lock_shared `void unlock_upgrade_and_lock_shared()`] + +[section:try_lock_upgrade_for `m.try_lock_upgrade_for(rel_time)`] [variablelist -[[Precondition:] [The current thread has upgrade ownership of `*this`.]] +[[Precondition:] [The calling thread has no ownership of the mutex. ]] -[[Effects:] [Atomically releases upgrade ownership of `*this` by the current thread and acquires shared ownership of `*this` without -blocking.]] +[[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. +Attempts to obtain upgrade lock ownership for the calling thread within the relative timeout specified by `rel_time`. +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()`). +The function returns within the timeout specified by `rel_time` only if it has obtained upgrade ownership of the mutex object.]] + +[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]] -[[Postcondition:] [The current thread has shared ownership of `*this`.]] +[[Synchronization:] [If `__try_lock_upgrade_for(rel_time)` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]] [[Throws:] [Nothing]] +[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]] + ] [endsect] -[section:unlock_and_lock_upgrade `void unlock_and_lock_upgrade()`] +[section:try_lock_upgrade_until `m.try_lock_upgrade_until(abs_time)`] [variablelist -[[Precondition:] [The current thread has exclusive ownership of `*this`.]] +[[Precondition:] [The calling thread has no ownership of the mutex. ]] + +[[Effects:] [The function attempts to obtain upgrade ownership of the mutex. +If `abs_time` has already passed, the function attempts to obtain upgrade ownership without blocking (as if by calling `__try_lock_upgrade()`). +The function returns before the absolute timeout specified by `abs_time` only if it has obtained upgrade ownership of the mutex object.]] + +[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]] + +[[Synchronization:] [If `__try_lock_upgrade_until(abs_time)` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]] + +[[Throws:] [Nothing]] + +[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]] + +] +[endsect] + + +[section:try_unlock_shared_and_lock `m.try_unlock_shared_and_lock()`] + +[variablelist + +[[Precondition:] [The calling thread must hold a shared lock on the mutex.]] + +[[Effects:] [The function attempts to atomically convert the ownership from shared to exclusive for the calling thread without blocking. +For this conversion to be successful, this thread must be the only thread holding any ownership of the lock. +If the conversion is not successful, the shared ownership of m is retained.]] + +[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]] + +[[Synchronization:] [If `__try_unlock_shared_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]] -[[Effects:] [Atomically releases exclusive ownership of `*this` by the current thread and acquires upgrade ownership of `*this` + +[[Throws:] [Nothing]] + +[[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]] + +] +[endsect] + +[section:try_unlock_shared_and_lock_for `m.try_unlock_shared_and_lock_for(rel_time)`] + +[variablelist + +[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]] + +[[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. +The function attempts to atomically convert the ownership from shared to exclusive for the calling thread within the relative timeout specified by `rel_time`. +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()`). +The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object. +For this conversion to be successful, this thread must be the only thread holding any ownership of the lock at the moment of conversion. +If the conversion is not successful, the shared ownership of the mutex is retained.]] + +[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]] + +[[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. ]] + +[[Throws:] [Nothing]] + +[[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]] + +] +[endsect] + + +[section:try_unlock_shared_and_lock_until `m.try_unlock_shared_and_lock_until(abs_time)`] + +[variablelist + +[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]] + +[[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`. +If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `try_unlock_shared_and_lock()`). +The function shall return before the absolute timeout specified by `abs_time` only if it has obtained exclusive ownership of the mutex object. +For this conversion to be successful, this thread must be the only thread holding any ownership of the lock at the moment of conversion. +If the conversion is not successful, the shared ownership of the mutex is retained.]] + +[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]] + +[[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. ]] + +[[Throws:] [Nothing]] + +[[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]] + +] +[endsect] + +[section:unlock_and_lock_shared `m.unlock_and_lock_shared()`] + +[variablelist + +[[Precondition:] [The calling thread shall hold an exclusive lock on `m`.]] + +[[Effects:] [Atomically converts the ownership from exclusive to shared for the calling thread.]] + +[[Postcondition:] [The current thread has shared ownership of `m`.]] + +[[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership of the same object.]] + +[[Throws:] [Nothing]] + +] +[endsect] + +[section:try_unlock_shared_and_lock_upgrade `m.try_unlock_shared_and_lock_upgrade()`] + +[variablelist + +[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]] + +[[Effects:] [The function attempts to atomically convert the ownership from shared to upgrade for the calling thread without blocking. +For this conversion to be successful, there must be no thread holding upgrade ownership of this object. +If the conversion is not successful, the shared ownership of the mutex is retained.]] + +[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]] + +[[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. ]] + +[[Throws:] [Nothing]] + +[[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]] + +] +[endsect] + + +[section:try_unlock_shared_and_lock_upgrade_for `m.try_unlock_shared_and_lock_upgrade_for(rel_time)`] + +[variablelist + +[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]] + +[[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. +The function attempts to atomically convert the ownership from shared to upgrade for the calling thread within the relative timeout specified by `rel_time`. +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()`). +The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object. +For this conversion to be successful, there must be no thread holding upgrade ownership of this object at the moment of conversion. +If the conversion is not successful, the shared ownership of m is retained.]] + +[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]] + +[[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. ]] + +[[Throws:] [Nothing]] + +[[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]] + + +] +[endsect] + +[section:try_unlock_shared_and_lock_upgrade_until `m.try_unlock_shared_and_lock_upgrade_until(abs_time)`] + +[variablelist + +[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]] + +[[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`. +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()`). +The function shall return before the absolute timeout specified by `abs_time` only if it has obtained upgrade ownership of the mutex object. +For this conversion to be successful, there must be no thread holding upgrade ownership of this object at the moment of conversion. +If the conversion is not successful, the shared ownership of the mutex is retained.]] + +[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]] + +[[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. ]] + +[[Throws:] [Nothing]] + +[[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]] + +] +[endsect] + +[section:unlock_and_lock_upgrade `m.unlock_and_lock_upgrade()`] + +[variablelist + +[[Precondition:] [The current thread has exclusive ownership of `m`.]] + +[[Effects:] [Atomically releases exclusive ownership of `m` by the current thread and acquires upgrade ownership of `m` without blocking.]] -[[Postcondition:] [The current thread has upgrade ownership of `*this`.]] +[[Postcondition:] [The current thread has upgrade ownership of `m`.]] + +[[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership of the same object.]] + +[[Throws:] [Nothing]] + +] +[endsect] + + +[section:unlock_upgrade_and_lock `m.unlock_upgrade_and_lock()`] + +[variablelist + +[[Precondition:] [The current thread has upgrade ownership of `m`.]] + +[[Effects:] [Atomically releases upgrade ownership of `m` by the current thread and acquires exclusive ownership of `m`. If +any other threads have shared ownership, blocks until exclusive ownership can be acquired.]] + +[[Postcondition:] [The current thread has exclusive ownership of `m`.]] + +[[Synchronization:] [This operation synchronizes with prior `__unlock_shared()` and subsequent lock operations that obtain ownership of the same object.]] + +[[Throws:] [Nothing]] + +] +[endsect] + +[section:try_unlock_upgrade_and_lock `m.try_unlock_upgrade_and_lock()`] + +[variablelist + +[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]] + +[[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread without blocking. +For this conversion to be successful, this thread must be the only thread holding any ownership of the lock. +If the conversion is not successful, the upgrade ownership of m is retained.]] + +[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]] + +[[Synchronization:] [If `__try_unlock_upgrade_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]] + +[[Throws:] [Nothing]] + +[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]] + + +] +[endsect] + +[section:try_unlock_upgrade_and_lock_for `m.try_unlock_upgrade_and_lock_for(rel_time)`] + +[variablelist + +[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]] + +[[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. +The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the relative timeout specified by `rel_time`. +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()`). +The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object. +For this conversion to be successful, this thread shall be the only thread holding any ownership of the lock at the moment of conversion. +If the conversion is not successful, the upgrade ownership of m is retained.]] + +[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]] + +[[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. ]] + +[[Throws:] [Nothing]] + +[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]] + +] +[endsect] + +[section:try_unlock_upgrade_and_lock_until `m.try_unlock_upgrade_and_lock_until(abs_time)`] + +[variablelist + +[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]] + +[[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`. +If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `__try_unlock_upgrade_and_lock()`). +The function shall return before the absolute timeout specified by `abs_time` only if it has obtained exclusive ownership of the mutex object. +For this conversion to be successful, this thread shall be the only thread holding any ownership of the lock at the moment of conversion. +If the conversion is not successful, the upgrade ownership of m is retained.]] + +[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]] + +[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]] + +[[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. ]] + +[[Throws:] [Nothing]] + +[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]] + +] +[endsect] + + +[section:unlock_upgrade_and_lock_shared `m.unlock_upgrade_and_lock_shared()`] + +[variablelist + +[[Precondition:] [The current thread has upgrade ownership of `m`.]] + +[[Effects:] [Atomically releases upgrade ownership of `m` by the current thread and acquires shared ownership of `m` without +blocking.]] + +[[Postcondition:] [The current thread has shared ownership of `m`.]] + +[[Synchronization:] [This operation synchronizes with prior `unlock_shared()` and subsequent lock operations that obtain ownership of the same object.]] [[Throws:] [Nothing]] @@ -310,6 +790,32 @@ without blocking.]] [section:locks Lock Types] + #include <boost/thread/locks.hpp> + + struct defer_lock_t {}; + struct try_to_lock_t {}; + struct adopt_lock_t {}; + constexpr defer_lock_t defer_lock; + constexpr try_to_lock_t try_to_lock; + constexpr adopt_lock_t adopt_lock; + + template<typename Lockable> + class lock_guard + template<typename Lockable> + class unique_lock; + template<typename Mutex> + void swap(unique_lock <Mutex>& lhs, unique_lock <Mutex>& rhs); + template<typename Lockable> + class shared_lock; + template<typename Mutex> + void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs); + template<typename Lockable> + class upgrade_lock; + template<typename Mutex> + void swap(upgrade_lock <Mutex>& lhs, upgrade_lock <Mutex>& rhs); + template <class Mutex> + class upgrade_to_unique_lock; + [section:lock_tags Lock option tags] #include <boost/thread/locks.hpp> @@ -403,41 +909,61 @@ object passed to the constructor.]] class unique_lock { public: - unique_lock(); + typedef Lockable mutex_type; + unique_lock() noexcept; explicit unique_lock(Lockable& m_); unique_lock(Lockable& m_,adopt_lock_t); - unique_lock(Lockable& m_,defer_lock_t); + unique_lock(Lockable& m_,defer_lock_t) noexcept; unique_lock(Lockable& m_,try_to_lock_t); - unique_lock(Lockable& m_,system_time const& target_time); + #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION + unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t) + template <class Clock, class Duration> + unique_lock(shared_lock<mutex_type>&& sl, + const chrono::time_point<Clock, Duration>& abs_time); + template <class Rep, class Period> + unique_lock(shared_lock<mutex_type>&& sl, + const chrono::duration<Rep, Period>& rel_time) + #endif + + template <class Clock, class Duration> + unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t); + template <class Rep, class Period> + unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d); ~unique_lock(); - unique_lock(detail::thread_move_t<unique_lock<Lockable> > other); - unique_lock(detail::thread_move_t<upgrade_lock<Lockable> > other); + unique_lock(unique_lock const&) = delete; + unique_lock& operator=(unique_lock const&) = delete; + unique_lock(unique_lock<Lockable>&& other) noexcept; + explicit unique_lock(upgrade_lock<Lockable>&& other) noexcept; - operator detail::thread_move_t<unique_lock<Lockable> >(); - detail::thread_move_t<unique_lock<Lockable> > move(); - unique_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other); - unique_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other); + unique_lock& operator=(unique_lock<Lockable>&& other) noexcept; - void swap(unique_lock& other); - void swap(detail::thread_move_t<unique_lock<Lockable> > other); + void swap(unique_lock& other) noexcept; + Lockable* release() noexcept; void lock(); bool try_lock(); - template<typename TimeDuration> - bool timed_lock(TimeDuration const& relative_time); - bool timed_lock(::boost::system_time const& absolute_time); + template <class Rep, class Period> + bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + template <class Clock, class Duration> + bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); - bool owns_lock() const; - operator ``['unspecified-bool-type]``() const; - bool operator!() const; + explicit operator bool() const noexcept; + bool owns_lock() const noexcept; + + Lockable* mutex() const noexcept; + + #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO + unique_lock(Lockable& m_,system_time const& target_time); + template<typename TimeDuration> + bool timed_lock(TimeDuration const& relative_time); + bool timed_lock(::boost::system_time const& absolute_time); + #endif - Lockable* mutex() const; - Lockable* release(); }; __unique_lock__ is more complex than __lock_guard__: not only does it provide for RAII-style locking, it also allows for deferring @@ -445,9 +971,10 @@ acquiring the lock until the __lock_ref__ member function is called explicitly, fashion, or with a timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the __lockable_concept_type__ object, or otherwise adopted a lock on the __lockable_concept_type__ object. -Specializations of __unique_lock__ model the __timed_lockable_concept__ if the supplied __lockable_concept_type__ type itself models -__timed_lockable_concept__ (e.g. `boost::unique_lock<boost::timed_mutex>`), or the __lockable_concept__ otherwise -(e.g. `boost::unique_lock<boost::mutex>`). +Specializations of __unique_lock__ model the __TimedLockable concept if the supplied `Lockable` type itself models +__TimedLockable concept (e.g. `boost::unique_lock<boost::timed_mutex>`), or the __Lockable concept if the supplied `Lockable` type itself models +__Lockable concept (e.g. `boost::unique_lock<boost::mutex>`), or the __BasicLockable concept if the supplied `Lockable` type itself models +__BasicLockable concept. An instance of __unique_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object @@ -533,6 +1060,82 @@ returns `false`.]] [endsect] +[section:constructor_sh_try `unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)`] + +[variablelist + +[[Requires:] [The supplied `Mutex` type must implement `__try_unlock_shared_and_lock()`.]] + +[[Effects:] [Constructs an object of type __unique_lock. Let `pm` be and `owns` the ownership state. Initializes `pm` with nullptr and `owns` with false. +If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.release()`. +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`.]] + +[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()->try_unlock_shared_and_lock()` returns `false`, `sl` is not modified.]] + +[[Throws:] [Nothing.]] + +[[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]] + +] + +[endsect] + + +[section:constructor_sh_until `unique_lock(shared_lock<mutex_type>&&, const chrono::time_point<Clock, Duration>&)`] + + template <class Clock, class Duration> + unique_lock(shared_lock<mutex_type>&& sl, + const chrono::time_point<Clock, Duration>& abs_time); + +[variablelist + +[[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_until(abs_time)`.]] + +[[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`. +If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.__release()`. +Else `sl.owns_lock()` 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`.]] + +[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_until(abs_time)` returns `false`, `sl` is not modified.]] + +[[Throws:] [Nothing.]] + +[[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]] + +] + +[endsect] + +[section:constructor_sh_for `unique_lock(shared_lock<mutex_type>&&, const chrono::duration<Rep, Period>&)`] + + template <class Rep, class Period> + unique_lock(shared_lock<mutex_type>&& sl, + const chrono::duration<Rep, Period>& rel_time) + +[variablelist + +[[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_for(rel_time)`.]] + +[[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`. +If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.__release()`. +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`.]] + +[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `false`, `sl` is not modified.]] + + +[[Postcondition:] [.]] + +[[Throws:] [Nothing.]] + +[[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]] + +] + +[endsect] + + + + + [section:constructor_abs_time `unique_lock(Lockable & m,boost::system_time const& abs_time)`] [variablelist @@ -551,6 +1154,43 @@ returns `false`.]] [endsect] +[section:constructor_time_point `template <class Clock, class Duration> unique_lock(Lockable & m,const chrono::time_point<Clock, Duration>& abs_time)`] + +[variablelist + +[[Effects:] [Stores a reference to `m`. Invokes +`m.__try_lock_until(abs_time)`, and takes ownership of the lock state if the call +returns `true`.]] + +[[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_until +returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__ +returns `false`.]] + +[[Throws:] [Any exceptions thrown by the call to `m.__try_lock_until(abs_time)`.]] + +] + +[endsect] + +[section:constructor_duration `template <class Rep, class Period> unique_lock(Lockable & m,const chrono::duration<Rep, Period>& abs_time)`] + + +[variablelist + +[[Effects:] [Stores a reference to `m`. Invokes +`m.__try_lock_for(rel_time)`, and takes ownership of the lock state if the call +returns `true`.]] + +[[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_for +returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__ +returns `false`.]] + +[[Throws:] [Any exceptions thrown by the call to `m.__try_lock_for(rel_time)`.]] + +] + +[endsect] + [section:destructor `~unique_lock()`] [variablelist @@ -590,13 +1230,11 @@ object associated with `*this`.]] [endsect] -[section:bool_conversion `operator unspecified-bool-type() const`] +[section:explicit_bool_conversion `explicit operator bool() const`] [variablelist -[[Returns:] [If __owns_lock_ref__ would return `true`, a value that evaluates to -`true` in boolean contexts, otherwise a value that evaluates to `false` in -boolean contexts.]] +[[Returns:] [`__owns_lock_ref__()`.]] [[Throws:] [Nothing.]] @@ -604,17 +1242,6 @@ boolean contexts.]] [endsect] -[section:operator_not `bool operator!() const`] - -[variablelist - -[[Returns:] [`!` __owns_lock_ref__.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] [section:release `Lockable* release()`] @@ -646,34 +1273,53 @@ __owns_lock_ref__ returns `false`.]] class shared_lock { public: + typedef Lockable mutex_type; + + // Shared locking shared_lock(); explicit shared_lock(Lockable& m_); shared_lock(Lockable& m_,adopt_lock_t); shared_lock(Lockable& m_,defer_lock_t); shared_lock(Lockable& m_,try_to_lock_t); - shared_lock(Lockable& m_,system_time const& target_time); - shared_lock(detail::thread_move_t<shared_lock<Lockable> > other); - shared_lock(detail::thread_move_t<unique_lock<Lockable> > other); - shared_lock(detail::thread_move_t<upgrade_lock<Lockable> > other); - + template <class Clock, class Duration> + shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t); + template <class Rep, class Period> + shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d); ~shared_lock(); - operator detail::thread_move_t<shared_lock<Lockable> >(); - detail::thread_move_t<shared_lock<Lockable> > move(); + shared_lock(shared_lock const&) = delete; + shared_lock& operator=(shared_lock const&) = delete; - shared_lock& operator=(detail::thread_move_t<shared_lock<Lockable> > other); - shared_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other); - shared_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other); - void swap(shared_lock& other); + shared_lock(shared_lock<Lockable> && other); + shared_lock& operator=(shared_lock<Lockable> && other); void lock(); bool try_lock(); - bool timed_lock(boost::system_time const& target_time); + template <class Rep, class Period> + bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + template <class Clock, class Duration> + bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); - operator ``['unspecified-bool-type]``() const; - bool operator!() const; + // Conversion from upgrade locking + explicit shared_lock(upgrade_lock<Lockable> && other); + + // Conversion from exclusive locking + explicit shared_lock(unique_lock<Lockable> && other); + + // Setters + void swap(shared_lock& other); + mutex_type* release() noexcept; + + // Getters + explicit operator bool() const; bool owns_lock() const; + mutex_type mutex() const; + + #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO + shared_lock(Lockable& m_,system_time const& target_time); + bool timed_lock(boost::system_time const& target_time); + #endif }; Like __unique_lock__, __shared_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied @@ -825,25 +1471,12 @@ object associated with `*this`.]] [endsect] -[section:bool_conversion `operator unspecified-bool-type() const`] - -[variablelist - -[[Returns:] [If __owns_lock_shared_ref__ would return `true`, a value that evaluates to -`true` in boolean contexts, otherwise a value that evaluates to `false` in -boolean contexts.]] -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:operator_not `bool operator!() const`] +[section:explicit_operator_bool `explicit operator bool() const`] [variablelist -[[Returns:] [`!` __owns_lock_shared_ref__.]] +[[Returns:] [__owns_lock_shared_ref__.]] [[Throws:] [Nothing.]] @@ -881,27 +1514,59 @@ __owns_lock_shared_ref__ returns `false`.]] class upgrade_lock { public: - explicit upgrade_lock(Lockable& m_); - - upgrade_lock(detail::thread_move_t<upgrade_lock<Lockable> > other); - upgrade_lock(detail::thread_move_t<unique_lock<Lockable> > other); - + typedef Lockable mutex_type; + + // Upgrade locking + + upgrade_lock(); + explicit upgrade_lock(mutex_type& m_); + upgrade_lock(mutex_type& m, defer_lock_t) noexcept; + upgrade_lock(mutex_type& m, try_to_lock_t); + upgrade_lock(mutex_type& m, adopt_lock_t); + template <class Clock, class Duration> + upgrade_lock(mutex_type& m, + const chrono::time_point<Clock, Duration>& abs_time); + template <class Rep, class Period> + upgrade_lock(mutex_type& m, + const chrono::duration<Rep, Period>& rel_time); ~upgrade_lock(); - operator detail::thread_move_t<upgrade_lock<Lockable> >(); - detail::thread_move_t<upgrade_lock<Lockable> > move(); + upgrade_lock(const upgrade_lock& other) = delete; + upgrade_lock& operator=(const upgrade_lock<Lockable> & other) = delete; - upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other); - upgrade_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other); - - void swap(upgrade_lock& other); + upgrade_lock(upgrade_lock<Lockable> && other); + upgrade_lock& operator=(upgrade_lock<Lockable> && other); void lock(); + bool try_lock(); + template <class Rep, class Period> + bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + template <class Clock, class Duration> + bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); - operator ``['unspecified-bool-type]``() const; - bool operator!() const; + #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION + // Conversion from shared locking + upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t); + template <class Clock, class Duration> + upgrade_lock(shared_lock<mutex_type>&& sl, + const chrono::time_point<Clock, Duration>& abs_time); + template <class Rep, class Period> + upgrade_lock(shared_lock<mutex_type>&& sl, + const chrono::duration<Rep, Period>& rel_time); + #endif + + // Conversion from exclusive locking + explicit upgrade_lock(unique_lock<Lockable> && other); + + // Setters + void swap(upgrade_lock& other); + mutex_type* release() noexcept; + + // Getters + explicit operator bool() const; bool owns_lock() const; + mutex_type mutex() const; }; Like __unique_lock__, __upgrade_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied @@ -917,7 +1582,7 @@ pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] t is destroyed, then the destructor will invoke [unlock_upgrade_ref_link `mutex()->unlock_upgrade()`]. The member functions of __upgrade_lock__ are not thread-safe. In particular, __upgrade_lock__ is intended to model the upgrade -ownership of a __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock +ownership of a __upgrade_lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock state (including the destructor) must be called by the same thread that acquired ownership of the lock state. [endsect] @@ -930,16 +1595,19 @@ state (including the destructor) must be called by the same thread that acquired class upgrade_to_unique_lock { public: + typedef Lockable mutex_type; explicit upgrade_to_unique_lock(upgrade_lock<Lockable>& m_); - ~upgrade_to_unique_lock(); - upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other); - upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other); + upgrade_to_unique_lock(upgrade_to_unique_lock const& other) = delete; + upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> const& other) = delete; + + upgrade_to_unique_lock(upgrade_to_unique_lock<Lockable> && other); + upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> && other); + void swap(upgrade_to_unique_lock& other); - operator ``['unspecified-bool-type]``() const; - bool operator!() const; + explicit operator bool() const; bool owns_lock() const; }; @@ -972,14 +1640,12 @@ __lockable_concept_type__ is downgraded back to ['upgrade ownership]. void lock(); bool try_lock(); void unlock(); - bool owns_lock() const; MutexType* mutex() const; MutexType* release(); - bool operator!() const; - typedef ``['unspecified-bool-type]`` bool_type; - operator bool_type() const; + explicit operator bool() const; + bool owns_lock() const; }; The member typedef `scoped_try_lock` is provided for each distinct @@ -989,11 +1655,157 @@ those of [unique_lock_link `boost::unique_lock<MutexType>`] for the same `MutexT that the constructor that takes a single reference to a mutex will call [try_lock_ref_link `m.try_lock()`] rather than `m.lock()`. +[endsect] +[endsect] + +[/ +[section:other_mutex Other Mutex Types] + +[section: reverse_mutex Class template `reverse_mutex`] + + #include <boost/thread/reverse_mutex.hpp> + + template<typename BasicLockable> + class reverse_mutex + { + public: + typedef BasicLockable mutex_type; + reverse_mutex(reverse_mutex const&) = delete; + reverse_mutex& operator=(reverse_mutex const&) = delete; + + explicit reverse_mutex(mutex_type& m_); + ~reverse_mutex(); + + void lock(); + void unlock(); + }; + +__reverse_mutex reverse the operations of a __BasicLockable, that unlocks the lockable when `lock()` is called and locks it when `unlock()` is called. + +[endsect] +[endsect] + +] + +[section:other_locks Other Lock Types] + + +[section:shared_lock_guard Class template `shared_lock_guard`] + + #include <boost/thread/shared_lock_guard.hpp> + + template<typename SharedLockable> + class shared_lock_guard + { + public: + explicit shared_lock_guard(SharedLockable& m_); + shared_lock_guard(SharedLockable& m_,boost::adopt_lock_t); + + ~shared_lock_guard(); + }; + +__shared_lock_guard is very simple: on construction it +acquires shared ownership of the implementation of the __shared_lockable_concept__ supplied as +the constructor parameter. On destruction, the ownership is released. This +provides simple RAII-style locking of a __shared_lockable_concept_type__ object, to facilitate exception-safe +shared locking and unlocking. +In addition, the `__shared_lock_guard_ca(SharedLockable &m, boost::adopt_lock_t)` constructor allows the __shared_lock_guard object to +take shared ownership of a lock already held by the current thread. + +[section:constructor `shared_lock_guard(SharedLockable & m)`] + +[variablelist + +[[Effects:] [Stores a reference to `m`. Invokes `m.__lock_shared()`.]] + +[[Throws:] [Any exception thrown by the call to `m.__lock_shared()`.]] + +] + +[endsect] + +[section:constructor_adopt `shared_lock_guard(SharedLockable & m,boost::adopt_lock_t)`] + +[variablelist + +[[Precondition:] [The current thread owns a lock on `m` equivalent to one +obtained by a call to `m.__lock_shared()`.]] + +[[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of +`m`.]] + +[[Throws:] [Nothing.]] + +] + +[endsect] + +[section:destructor `~shared_lock_guard()`] + +[variablelist + +[[Effects:] [Invokes `m.__unlock_shared()` on the __shared_lockable_concept_type__ object passed to the constructor.]] + +[[Throws:] [Nothing.]] + +] [endsect] [endsect] +[section:reverse_lock Class template `reverse_lock`] + + #include <boost/thread/reverse_lock.hpp> + + template<typename Lock> + class reverse_lock + { + public: + reverse_lock(reverse_lock const&) = delete; + reverse_lock& operator=(reverse_lock const&) = delete; + + explicit reverse_lock(Lock& m_); + ~reverse_lock(); + }; + +__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. + +An instance of __reverse_lock doesn't ['own] the lock never. + +[section:constructor `reverse_lock(Lock & m)`] + +[variablelist + +[[Effects:] [Stores a reference to `m`. Invokes `m.__unlock()` if `m` owns his lock and then stores the mutex by calling `m.__release()`.]] + +[[Postcondition:] [`!m.__owns_lock() && m.__mutex()==0`.]] + +[[Throws:] [Any exception thrown by the call to `m.__unlock()`.]] + +] + +[endsect] + + +[section:destructor `~reverse_lock()`] + +[variablelist + +[[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.]] + +[[Throws:] [Nothing.]] + +] + +[endsect] + + +[endsect] + +[endsect] + + [section:lock_functions Lock functions] [section:lock_multiple Non-member function `lock(Lockable1,Lockable2,...)`] |