| Home | Libraries | People | FAQ | More

## Synchronization

### Tutorial

Handling mutexes in C++ is an excellent tutorial. You need just replace std and ting by boost.

Mutex, Lock, Condition Variable Rationale adds rationale for the design decisions made for mutexes, locks and condition variables.

### Mutex Concepts

A mutex object facilitates protection against data races and allows thread-safe synchronization of data between threads. A thread obtains ownership of a mutex object by calling one of the lock functions and relinquishes ownership by calling the corresponding unlock function. Mutexes may be either recursive or non-recursive, and may grant simultaneous ownership to one or many threads. Boost.Thread supplies recursive and non-recursive mutexes with exclusive ownership semantics, along with a shared ownership (multiple-reader / single-writer) mutex.

Boost.Thread supports four basic concepts for lockable objects: `Lockable`, `TimedLockable`, `SharedLockable` and `UpgradeLockable`. Each mutex type implements one or more of these concepts, as do the various lock types.

#### `BasicLockable` Concept

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`):

- `m.`lock`();`
- `m.`unlock`();`

Lock ownership acquired through a call to `lock()` must be released through a call to `unlock()`.

##### `m.lock();`

Effects:

  The current thread blocks until ownership can be obtained for the current thread.

Postcondition:

  The current thread owns `m`.

Return type:

  `void`.

Throws:

  `boost::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.

##### `m.unlock();`

Precondition:

  The current thread owns `m`.

Effects:

  Releases ownership by the current thread.

Return type:

  `void`.

Postcondition:

  The current thread no longer owns `m`.

Throws:

  Nothing.

#### `Lockable` Concept

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`):

- `m.`try_lock`()`

Lock ownership acquired through a call to `try_lock()` must be released through a call to `unlock()`.

##### `m.try_lock()`

Effects:

  Attempt to obtain ownership for the current thread without blocking.

Return type:

  `bool`.

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.

#### `TimedLockable` Concept

The `TimedLockable` concept refines the `Lockable` concept to add support for timeouts when trying to acquire the lock.

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`.

##### `m.try_lock_until(abs_time)`

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()`.

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.

##### `m.try_lock_for(rel_time)`

Effects:

  As-if ``try_lock_until`(chrono::steady_clock::now() + rel_time)`.

###### 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`(rel_time)`
- `m.`timed_lock`(abs_time)`

Lock ownership acquired through a call to `timed_lock()` must be released through a call to `unlock()`.

##### `m.timed_lock(abs_time)`

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()`.

Returns:

  `true` if ownership was obtained for the current thread, `false` otherwise.

Postcondition:

  If the call returns `true`, the current thread owns `m`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `m.timed_lock(rel_time)`

Effects:

  As-if `timed_lock(boost::get_system_time()+rel_time)`.

#### `SharedLockable` Concept

The `SharedLockable` concept is a refinement of the `TimedLockable` concept that allows for shared ownership as well as exclusive ownership. This is the standard multiple-reader / single-write model: at most one thread can have exclusive ownership, and if any thread does have exclusive ownership, no other threads can have shared or exclusive ownership. Alternatively, many threads may have shared ownership.

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_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()`, `try_lock_shared()`, `try_lock_shared_for` or `try_lock_shared_until` must be released through a call to `unlock_shared()`.

##### `m.lock_shared()`

Effects:

  The current thread blocks until shared ownership can be obtained for the current thread.

Postcondition:

  The current thread has shared ownership of `m`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `m.try_lock_shared()`

Effects:

  Attempt to obtain shared ownership for the current thread without blocking.

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 `m`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `m.try_lock_shared_for(rel_time)`

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()`.

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:

  `boost::thread_resource_error` if an error occurs.

##### `m.try_lock_shared_until(abs_time))`

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()`.

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:

  `boost::thread_resource_error` if an error occurs.

##### `m.unlock_shared()`

Precondition:

  The current thread has shared ownership of `m`.

Effects:

  Releases shared ownership of `m` by the current thread.

Postcondition:

  The current thread no longer has shared ownership of `m`.

Throws:

  Nothing

###### 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()` must be released through a call to `unlock_shared()`.

##### `m.timed_lock_shared(abs_time)`

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()`.

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:

  `boost::thread_resource_error` if an error occurs.

#### `UpgradeLockable` Concept

The `UpgradeLockable` concept is a refinement of the `SharedLockable` concept that allows for upgradable ownership as well as shared ownership and exclusive ownership. This is an extension to the multiple-reader / single-write model provided by the `SharedLockable` concept: a single thread may have upgradable ownership at the same time as others have shared ownership. The thread with upgradable ownership may at any time attempt to upgrade that ownership to exclusive ownership. If no other threads have shared ownership, the upgrade is completed immediately, and the thread now has exclusive ownership, which must be relinquished by a call to `unlock()`, just as if it had been acquired by a call to `lock()`.

If a thread with upgradable ownership tries to upgrade whilst other threads have shared ownership, the attempt will fail and the thread will block until exclusive ownership can be acquired.

Ownership can also be downgraded as well as upgraded: exclusive ownership of an implementation of the `UpgradeLockable` concept can be downgraded to upgradable ownership or shared ownership, and upgradable ownership can be downgraded to plain shared ownership.

A type `L` meets the `UpgradeLockable` requirements if it meets the `SharedLockable` 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 ownership acquired through a call to `lock_upgrade()` must be released through a call to `unlock_upgrade()`. 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.

##### `m.lock_upgrade()`

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 `m`.

Synchronization:

  Prior ``unlock_upgrade`()` operations on the same object synchronize with this operation.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `m.unlock_upgrade()`

Precondition:

  The current thread has upgrade ownership of `m`.

Effects:

  Releases upgrade ownership of `m` by the current thread.

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

##### `m.try_lock_upgrade()`

Precondition:

  The calling thread has no ownership of the mutex.

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`.

Synchronization:

  If ``try_lock_upgrade`()` returns true, prior ``unlock_upgrade`()` operations on the same object synchronize with this operation.

Throws:

  Nothing

##### `m.try_lock_upgrade_for(rel_time)`

Precondition:

  The calling thread has no ownership of 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. 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`.

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

##### `m.try_lock_upgrade_until(abs_time)`

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

##### `m.try_unlock_shared_and_lock()`

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.

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

##### `m.try_unlock_shared_and_lock_for(rel_time)`

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

##### `m.try_unlock_shared_and_lock_until(abs_time)`

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

##### `m.unlock_and_lock_shared()`

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

##### `m.try_unlock_shared_and_lock_upgrade()`

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

##### `m.try_unlock_shared_and_lock_upgrade_for(rel_time)`

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

##### `m.try_unlock_shared_and_lock_upgrade_until(abs_time)`

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

##### `m.unlock_and_lock_upgrade()`

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 `m`.

Synchronization:

  This operation synchronizes with subsequent lock operations that obtain ownership of the same object.

Throws:

  Nothing

##### `m.unlock_upgrade_and_lock()`

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

##### `m.try_unlock_upgrade_and_lock()`

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

##### `m.try_unlock_upgrade_and_lock_for(rel_time)`

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

##### `m.try_unlock_upgrade_and_lock_until(abs_time)`

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

##### `m.unlock_upgrade_and_lock_shared()`

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

### Lock Types

    //#include <boost/thread/locks.hpp>

    namespace boost
    {
      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;
    }

#### Lock option tags

    #include <boost/thread/locks.hpp>

    struct defer_lock_t {};
    struct try_to_lock_t {};
    struct adopt_lock_t {};
    const defer_lock_t defer_lock;
    const try_to_lock_t try_to_lock;
    const adopt_lock_t adopt_lock;

These tags are used in scoped locks constructors to specify a specific behavior.

- `defer_lock_t`: is used to construct the scoped lock without locking it.
- `try_to_lock_t`: is used to construct the scoped lock trying to lock it.
- `adopt_lock_t`: is used to construct the scoped lock without locking it but adopting ownership.

#### Class template `lock_guard`

    //#include <boost/thread/locks.hpp>

    template<typename Lockable>
    class lock_guard
    {
    public:
        explicit lock_guard(Lockable& m_);
        lock_guard(Lockable& m_,boost::adopt_lock_t);

        ~lock_guard();
    };

`boost::lock_guard` is very simple: on construction it acquires ownership of the implementation of the `Lockable` concept supplied as the constructor parameter. On destruction, the ownership is released. This provides simple RAII-style locking of a `Lockable` object, to facilitate exception-safe locking and unlocking. In addition, the `lock_guard(Lockable & m,boost::adopt_lock_t)` constructor allows the `boost::lock_guard` object to take ownership of a lock already held by the current thread.

##### `lock_guard(Lockable & m)`

Effects:

  Stores a reference to `m`. Invokes `m.lock()`.

Throws:

  Any exception thrown by the call to `m.lock()`.

##### `lock_guard(Lockable & m,boost::adopt_lock_t)`

Precondition:

  The current thread owns a lock on `m` equivalent to one obtained by a call to `m.lock()`.

Effects:

  Stores a reference to `m`. Takes ownership of the lock state of `m`.

Throws:

  Nothing.

##### `~lock_guard()`

Effects:

  Invokes `m.unlock()` on the `Lockable` object passed to the constructor.

Throws:

  Nothing.

#### Class template `unique_lock`

    //#include <boost/thread/locks.hpp>

    template<typename Lockable>
    class unique_lock
    {
    public:
        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) noexcept;
        unique_lock(Lockable& m_,try_to_lock_t);

    #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(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;

        unique_lock& operator=(unique_lock<Lockable>&& other) noexcept;

        void swap(unique_lock& other) noexcept;
        Lockable* release() noexcept;

        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();

        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

    };

`boost::unique_lock` is more complex than `boost::lock_guard`: not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the `lock()` member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a timeout. Consequently, `unlock()` is only called in the destructor if the lock object has locked the `Lockable` object, or otherwise adopted a lock on the `Lockable` object.

Specializations of `boost::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 `boost::unique_lock` is said to own the lock state of a `Lockable` `m` if `mutex()` returns a pointer to `m` and `owns_lock()` returns `true`. If an object that owns the lock state of a `Lockable` object is destroyed, then the destructor will invoke `mutex()->unlock()`.

The member functions of `boost::unique_lock` are not thread-safe. In particular, `boost::unique_lock` is intended to model the ownership of a `Lockable` 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.

##### `unique_lock()`

Effects:

  Creates a lock object with no associated mutex.

Postcondition:

  `owns_lock()` returns `false`. `mutex()` returns `NULL`.

Throws:

  Nothing.

##### `unique_lock(Lockable & m)`

Effects:

  Stores a reference to `m`. Invokes `m.lock()`.

Postcondition:

  `owns_lock()` returns `true`. `mutex()` returns `&m`.

Throws:

  Any exception thrown by the call to `m.lock()`.

##### `unique_lock(Lockable & m,boost::adopt_lock_t)`

Precondition:

  The current thread owns an exclusive lock on `m`.

Effects:

  Stores a reference to `m`. Takes ownership of the lock state of `m`.

Postcondition:

  `owns_lock()` returns `true`. `mutex()` returns `&m`.

Throws:

  Nothing.

##### `unique_lock(Lockable & m,boost::defer_lock_t)`

Effects:

  Stores a reference to `m`.

Postcondition:

  `owns_lock()` returns `false`. `mutex()` returns `&m`.

Throws:

  Nothing.

##### `unique_lock(Lockable & m,boost::try_to_lock_t)`

Effects:

  Stores a reference to `m`. Invokes `m.try_lock()`, and takes ownership of the lock state if the call returns `true`.

Postcondition:

  `mutex()` returns `&m`. If the call to `try_lock()` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Nothing.

##### `unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)`

Requires:

  The supplied `Mutex` type must implement ``try_unlock_shared_and_lock`()`.

Effects:

  Constructs an object of type `boost::unique_lock`. Let `pm` be the pointer to the mutex 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

##### `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);

Requires:

  The supplied `Mutex` type shall implement ``try_unlock_shared_and_lock_until`(abs_time)`.

Effects:

  Constructs an object of type ``boost::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

##### `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)

Requires:

  The supplied `Mutex` type shall implement ``try_unlock_shared_and_lock_for`(rel_time)`.

Effects:

  Constructs an object of type ``boost::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

##### `unique_lock(Lockable & m,boost::system_time const& abs_time)`

Effects:

  Stores a reference to `m`. Invokes `m.timed_lock(abs_time)`, and takes ownership of the lock state if the call returns `true`.

Postcondition:

  `mutex()` returns `&m`. If the call to `timed_lock()` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Any exceptions thrown by the call to `m.timed_lock(abs_time)`.

##### `template <class Clock, class Duration> unique_lock(Lockable & m,const chrono::time_point<Clock, Duration>& abs_time)`

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()` returns `&m`. If the call to `try_lock_until` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Any exceptions thrown by the call to `m.`try_lock_until`(abs_time)`.

##### `template <class Rep, class Period> unique_lock(Lockable & m,const chrono::duration<Rep, Period>& abs_time)`

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()` returns `&m`. If the call to `try_lock_for` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Any exceptions thrown by the call to `m.`try_lock_for`(rel_time)`.

##### `~unique_lock()`

Effects:

  Invokes `mutex()` `->` `unlock()` if `owns_lock()` returns `true`.

Throws:

  Nothing.

##### `bool owns_lock() const`

Returns:

  `true` if the `*this` owns the lock on the `Lockable` object associated with `*this`.

Throws:

  Nothing.

##### `Lockable* mutex() const`

Returns:

  A pointer to the `Lockable` object associated with `*this`, or `NULL` if there is no such object.

Throws:

  Nothing.

##### `explicit operator bool() const`

Returns:

  ``owns_lock()`()`.

Throws:

  Nothing.

##### `Lockable* release()`

Effects:

  The association between `*this` and the `Lockable` object is removed, without affecting the lock state of the `Lockable` object. If `owns_lock()` would have returned `true`, it is the responsibility of the calling code to ensure that the `Lockable` is correctly unlocked.

Returns:

  A pointer to the `Lockable` object associated with `*this` at the point of the call, or `NULL` if there is no such object.

Throws:

  Nothing.

Postcondition:

  `*this` is no longer associated with any `Lockable` object. `mutex()` returns `NULL` and `owns_lock()` returns `false`.

#### Class template `shared_lock`

    //#include <boost/thread/locks.hpp>

    template<typename Lockable>
    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);
        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();

        shared_lock(shared_lock const&) = delete;
        shared_lock& operator=(shared_lock const&) = delete;

        shared_lock(shared_lock<Lockable> && other);
        shared_lock& operator=(shared_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();

        // 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 `boost::unique_lock`, `boost::shared_lock` models the `Lockable` concept, but rather than acquiring unique ownership of the supplied `Lockable` object, locking an instance of `boost::shared_lock` acquires shared ownership.

Like `boost::unique_lock`, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the `lock()` member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a timeout. Consequently, `unlock()` is only called in the destructor if the lock object has locked the `Lockable` object, or otherwise adopted a lock on the `Lockable` object.

An instance of `boost::shared_lock` is said to own the lock state of a `Lockable` `m` if `mutex()` returns a pointer to `m` and `owns_lock()` returns `true`. If an object that owns the lock state of a `Lockable` object is destroyed, then the destructor will invoke `mutex()->unlock_shared()`.

The member functions of `boost::shared_lock` are not thread-safe. In particular, `boost::shared_lock` is intended to model the shared ownership of a `Lockable` 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.

##### `shared_lock()`

Effects:

  Creates a lock object with no associated mutex.

Postcondition:

  `owns_lock()` returns `false`. `mutex()` returns `NULL`.

Throws:

  Nothing.

##### `shared_lock(Lockable & m)`

Effects:

  Stores a reference to `m`. Invokes `m.lock_shared()`.

Postcondition:

  `owns_lock()` returns `true`. `mutex()` returns `&m`.

Throws:

  Any exception thrown by the call to `m.lock_shared()`.

##### `shared_lock(Lockable & m,boost::adopt_lock_t)`

Precondition:

  The current thread owns an exclusive lock on `m`.

Effects:

  Stores a reference to `m`. Takes ownership of the lock state of `m`.

Postcondition:

  `owns_lock()` returns `true`. `mutex()` returns `&m`.

Throws:

  Nothing.

##### `shared_lock(Lockable & m,boost::defer_lock_t)`

Effects:

  Stores a reference to `m`.

Postcondition:

  `owns_lock()` returns `false`. `mutex()` returns `&m`.

Throws:

  Nothing.

##### `shared_lock(Lockable & m,boost::try_to_lock_t)`

Effects:

  Stores a reference to `m`. Invokes `m.try_lock_shared()`, and takes ownership of the lock state if the call returns `true`.

Postcondition:

  `mutex()` returns `&m`. If the call to `try_lock_shared()` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Nothing.

##### `shared_lock(Lockable & m,boost::system_time const& abs_time)`

Effects:

  Stores a reference to `m`. Invokes `m.timed_lock(abs_time)`, and takes ownership of the lock state if the call returns `true`.

Postcondition:

  `mutex()` returns `&m`. If the call to `timed_lock_shared()` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Any exceptions thrown by the call to `m.timed_lock(abs_time)`.

##### `~shared_lock()`

Effects:

  Invokes `mutex()` `->` `unlock_shared()` if `owns_lock()` returns `true`.

Throws:

  Nothing.

##### `bool owns_lock() const`

Returns:

  `true` if the `*this` owns the lock on the `Lockable` object associated with `*this`.

Throws:

  Nothing.

##### `Lockable* mutex() const`

Returns:

  A pointer to the `Lockable` object associated with `*this`, or `NULL` if there is no such object.

Throws:

  Nothing.

##### `explicit operator bool() const`

Returns:

  `owns_lock()`.

Throws:

  Nothing.

##### `Lockable* release()`

Effects:

  The association between `*this` and the `Lockable` object is removed, without affecting the lock state of the `Lockable` object. If `owns_lock()` would have returned `true`, it is the responsibility of the calling code to ensure that the `Lockable` is correctly unlocked.

Returns:

  A pointer to the `Lockable` object associated with `*this` at the point of the call, or `NULL` if there is no such object.

Throws:

  Nothing.

Postcondition:

  `*this` is no longer associated with any `Lockable` object. `mutex()` returns `NULL` and `owns_lock()` returns `false`.

#### Class template `upgrade_lock`

    //#include <boost/thread/locks.hpp>

    template<typename Lockable>
    class upgrade_lock
    {
    public:
        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();

        upgrade_lock(const upgrade_lock& other) = delete;
        upgrade_lock& operator=(const upgrade_lock<Lockable> & other) = delete;

        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();

    #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 `boost::unique_lock`, `boost::upgrade_lock` models the `Lockable` concept, but rather than acquiring unique ownership of the supplied `Lockable` object, locking an instance of `boost::upgrade_lock` acquires upgrade ownership.

Like `boost::unique_lock`, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the `lock()` member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a timeout. Consequently, `unlock()` is only called in the destructor if the lock object has locked the `Lockable` object, or otherwise adopted a lock on the `Lockable` object.

An instance of `boost::upgrade_lock` is said to own the lock state of a `Lockable` `m` if `mutex()` returns a pointer to `m` and `owns_lock()` returns `true`. If an object that owns the lock state of a `Lockable` object is destroyed, then the destructor will invoke `mutex()->unlock_upgrade()`.

The member functions of `boost::upgrade_lock` are not thread-safe. In particular, `boost::upgrade_lock` is intended to model the upgrade ownership of a `UpgradeLockable` 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.

#### Class template `upgrade_to_unique_lock`

    #include <boost/thread/locks.hpp>

    template <class Lockable>
    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(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);

        explicit operator bool() const;
        bool owns_lock() const;
    };

`boost::upgrade_to_unique_lock` allows for a temporary upgrade of an `boost::upgrade_lock` to exclusive ownership. When constructed with a reference to an instance of `boost::upgrade_lock`, if that instance has upgrade ownership on some `Lockable` object, that ownership is upgraded to exclusive ownership. When the `boost::upgrade_to_unique_lock` instance is destroyed, the ownership of the `Lockable` is downgraded back to upgrade ownership.

#### Mutex-specific class `scoped_try_lock`

    class MutexType::scoped_try_lock
    {
    private:
        MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>& other);
        MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>& other);
    public:
        MutexType::scoped_try_lock();
        explicit MutexType::scoped_try_lock(MutexType& m);
        MutexType::scoped_try_lock(MutexType& m_,adopt_lock_t);
        MutexType::scoped_try_lock(MutexType& m_,defer_lock_t);
        MutexType::scoped_try_lock(MutexType& m_,try_to_lock_t);

        MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>&& other);
        MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>&& other);

        void swap(MutexType::scoped_try_lock&& other);

        void lock();
        bool try_lock();
        void unlock();

        MutexType* mutex() const;
        MutexType* release();

        explicit operator bool() const;
        bool owns_lock() const;
    };

The member typedef `scoped_try_lock` is provided for each distinct `MutexType` as a typedef to a class with the preceding definition. The semantics of each constructor and member function are identical to those of `boost::unique_lock<MutexType>` for the same `MutexType`, except that the constructor that takes a single reference to a mutex will call `m.try_lock()` rather than `m.lock()`.

### Other Lock Types

#### Class template `shared_lock_guard`

    // #include <boost/thread/shared_lock_guard.hpp>
    namespace boost
    {
      template<typename SharedLockable>
      class shared_lock_guard
      {
      public:
          shared_lock_guard(shared_lock_guard const&) = delete;
          shared_lock_guard& operator=(shared_lock_guard const&) = delete;

          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 `SharedLockable` concept supplied as the constructor parameter. On destruction, the ownership is released. This provides simple RAII-style locking of a `SharedLockable` object, to facilitate exception-safe shared locking and unlocking. In addition, the ``shared_lock_guard`(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.

##### `shared_lock_guard(SharedLockable & m)`

Effects:

  Stores a reference to `m`. Invokes `m.`lock_shared()`()`.

Throws:

  Any exception thrown by the call to `m.`lock_shared()`()`.

##### `shared_lock_guard(SharedLockable & m,boost::adopt_lock_t)`

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.

##### `~shared_lock_guard()`

Effects:

  Invokes `m.`unlock_shared()`()` on the `SharedLockable` object passed to the constructor.

Throws:

  Nothing.

#### Class template `reverse_lock`

    // #include <boost/thread/reverse_lock.hpp>
    namespace boost
    {

      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.

##### `reverse_lock(Lock & m)`

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`()`.

##### `~reverse_lock()`

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.

### Lock functions

#### Non-member function `lock(Lockable1,Lockable2,...)`

    // #include <boost/thread/locks.hpp>
    namespace boost
    {

      template<typename Lockable1,typename Lockable2>
      void lock(Lockable1& l1,Lockable2& l2);

      template<typename Lockable1,typename Lockable2,typename Lockable3>
      void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);

      template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
      void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);

      template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
      void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);

    }

Effects:

  Locks the `Lockable` objects supplied as arguments in an unspecified and indeterminate order in a way that avoids deadlock. It is safe to call this function concurrently from multiple threads with the same mutexes (or other lockable objects) in different orders without risk of deadlock. If any of the `lock()` or `try_lock()` operations on the supplied `Lockable` objects throws an exception any locks acquired by the function will be released before the function exits.

Throws:

  Any exceptions thrown by calling `lock()` or `try_lock()` on the supplied `Lockable` objects.

Postcondition:

  All the supplied `Lockable` objects are locked by the calling thread.

#### Non-member function `lock(begin,end)`

    template<typename ForwardIterator>
    void lock(ForwardIterator begin,ForwardIterator end);

Preconditions:

  The `value_type` of `ForwardIterator` must implement the `Lockable` concept

Effects:

  Locks all the `Lockable` objects in the supplied range in an unspecified and indeterminate order in a way that avoids deadlock. It is safe to call this function concurrently from multiple threads with the same mutexes (or other lockable objects) in different orders without risk of deadlock. If any of the `lock()` or `try_lock()` operations on the `Lockable` objects in the supplied range throws an exception any locks acquired by the function will be released before the function exits.

Throws:

  Any exceptions thrown by calling `lock()` or `try_lock()` on the supplied `Lockable` objects.

Postcondition:

  All the `Lockable` objects in the supplied range are locked by the calling thread.

#### Non-member function `try_lock(Lockable1,Lockable2,...)`

    template<typename Lockable1,typename Lockable2>
    int try_lock(Lockable1& l1,Lockable2& l2);

    template<typename Lockable1,typename Lockable2,typename Lockable3>
    int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);

    template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
    int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);

    template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
    int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);

Effects:

  Calls `try_lock()` on each of the `Lockable` objects supplied as arguments. If any of the calls to `try_lock()` returns `false` then all locks acquired are released and the zero-based index of the failed lock is returned.

  If any of the `try_lock()` operations on the supplied `Lockable` objects throws an exception any locks acquired by the function will be released before the function exits.

Returns:

  `-1` if all the supplied `Lockable` objects are now locked by the calling thread, the zero-based index of the object which could not be locked otherwise.

Throws:

  Any exceptions thrown by calling `try_lock()` on the supplied `Lockable` objects.

Postcondition:

  If the function returns `-1`, all the supplied `Lockable` objects are locked by the calling thread. Otherwise any locks acquired by this function will have been released.

#### Non-member function `try_lock(begin,end)`

    template<typename ForwardIterator>
    ForwardIterator try_lock(ForwardIterator begin,ForwardIterator end);

Preconditions:

  The `value_type` of `ForwardIterator` must implement the `Lockable` concept

Effects:

  Calls `try_lock()` on each of the `Lockable` objects in the supplied range. If any of the calls to `try_lock()` returns `false` then all locks acquired are released and an iterator referencing the failed lock is returned.

  If any of the `try_lock()` operations on the supplied `Lockable` objects throws an exception any locks acquired by the function will be released before the function exits.

Returns:

  `end` if all the supplied `Lockable` objects are now locked by the calling thread, an iterator referencing the object which could not be locked otherwise.

Throws:

  Any exceptions thrown by calling `try_lock()` on the supplied `Lockable` objects.

Postcondition:

  If the function returns `end` then all the `Lockable` objects in the supplied range are locked by the calling thread, otherwise all locks acquired by the function have been released.

### Mutex Types

#### Class `mutex`

    #include <boost/thread/mutex.hpp>

    class mutex:
        boost::noncopyable
    {
    public:
        mutex();
        ~mutex();

        void lock();
        bool try_lock();
        void unlock();

        typedef platform-specific-type native_handle_type;
        native_handle_type native_handle();

        typedef unique_lock<mutex> scoped_lock;
        typedef unspecified-type scoped_try_lock;
    };

`boost::mutex` implements the `Lockable` concept to provide an exclusive-ownership mutex. At most one thread can own the lock on a given instance of `boost::mutex` at any time. Multiple concurrent calls to `lock()`, `try_lock()` and `unlock()` shall be permitted.

##### Member function `native_handle()`

    typedef platform-specific-type native_handle_type;
    native_handle_type native_handle();

Effects:

  Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.

Throws:

  Nothing.

#### Typedef `try_mutex`

    #include <boost/thread/mutex.hpp>

    typedef mutex try_mutex;

`boost::try_mutex` is a `typedef` to `boost::mutex`, provided for backwards compatibility with previous releases of boost.

#### Class `timed_mutex`

    #include <boost/thread/mutex.hpp>

    class timed_mutex:
        boost::noncopyable
    {
    public:
        timed_mutex();
        ~timed_mutex();

        void lock();
        void unlock();
        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>& t);

        typedef platform-specific-type native_handle_type;
        native_handle_type native_handle();

        typedef unique_lock<timed_mutex> scoped_timed_lock;
        typedef unspecified-type scoped_try_lock;
        typedef scoped_timed_lock scoped_lock;

    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
        bool timed_lock(system_time const & abs_time);
        template<typename TimeDuration>
        bool timed_lock(TimeDuration const & relative_time);
    #endif

    };

`boost::timed_mutex` implements the `TimedLockable` concept to provide an exclusive-ownership mutex. At most one thread can own the lock on a given instance of `boost::timed_mutex` at any time. Multiple concurrent calls to `lock()`, `try_lock()`, `timed_lock()`, `timed_lock()` and `unlock()` shall be permitted.

##### Member function `native_handle()`

    typedef platform-specific-type native_handle_type;
    native_handle_type native_handle();

Effects:

  Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.

Throws:

  Nothing.

#### Class `recursive_mutex`

    #include <boost/thread/recursive_mutex.hpp>

    class recursive_mutex:
        boost::noncopyable
    {
    public:
        recursive_mutex();
        ~recursive_mutex();

        void lock();
        bool try_lock() noexcept;
        void unlock();

        typedef platform-specific-type native_handle_type;
        native_handle_type native_handle();

        typedef unique_lock<recursive_mutex> scoped_lock;
        typedef unspecified-type scoped_try_lock;
    };

`boost::recursive_mutex` implements the `Lockable` concept to provide an exclusive-ownership recursive mutex. At most one thread can own the lock on a given instance of `boost::recursive_mutex` at any time. Multiple concurrent calls to `lock()`, `try_lock()` and `unlock()` shall be permitted. A thread that already has exclusive ownership of a given `boost::recursive_mutex` instance can call `lock()` or `try_lock()` to acquire an additional level of ownership of the mutex. `unlock()` must be called once for each level of ownership acquired by a single thread before ownership can be acquired by another thread.

##### Member function `native_handle()`

    typedef platform-specific-type native_handle_type;
    native_handle_type native_handle();

Effects:

  Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.

Throws:

  Nothing.

#### Typedef `recursive_try_mutex`

    #include <boost/thread/recursive_mutex.hpp>

    typedef recursive_mutex recursive_try_mutex;

`boost::recursive_try_mutex` is a `typedef` to `boost::recursive_mutex`, provided for backwards compatibility with previous releases of boost.

#### Class `recursive_timed_mutex`

    #include <boost/thread/recursive_mutex.hpp>

    class recursive_timed_mutex:
        boost::noncopyable
    {
    public:
        recursive_timed_mutex();
        ~recursive_timed_mutex();

        void lock();
        bool try_lock() noexcept;
        void unlock();

        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>& t);

        typedef platform-specific-type native_handle_type;
        native_handle_type native_handle();

        typedef unique_lock<recursive_timed_mutex> scoped_lock;
        typedef unspecified-type scoped_try_lock;
        typedef scoped_lock scoped_timed_lock;

    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
        bool timed_lock(system_time const & abs_time);
        template<typename TimeDuration>
        bool timed_lock(TimeDuration const & relative_time);
    #endif

    };

`boost::recursive_timed_mutex` implements the `TimedLockable` concept to provide an exclusive-ownership recursive mutex. At most one thread can own the lock on a given instance of `boost::recursive_timed_mutex` at any time. Multiple concurrent calls to `lock()`, `try_lock()`, `timed_lock()`, `timed_lock()` and `unlock()` shall be permitted. A thread that already has exclusive ownership of a given `boost::recursive_timed_mutex` instance can call `lock()`, `timed_lock()`, `timed_lock()` or `try_lock()` to acquire an additional level of ownership of the mutex. `unlock()` must be called once for each level of ownership acquired by a single thread before ownership can be acquired by another thread.

##### Member function `native_handle()`

    typedef platform-specific-type native_handle_type;
    native_handle_type native_handle();

Effects:

  Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.

Throws:

  Nothing.

#### Class `shared_mutex`

    #include <boost/thread/shared_mutex.hpp>

    class shared_mutex
    {
    public:
        shared_mutex(shared_mutex const&) = delete;
        shared_mutex& operator=(shared_mutex const&) = delete;

        shared_mutex();
        ~shared_mutex();

        void lock_shared();
        bool try_lock_shared();
        template <class Rep, class Period>
        bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
        template <class Clock, class Duration>
        bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
        void unlock_shared();

        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();

    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
        // use upgrade_mutex instead.
        void lock_upgrade();
        void unlock_upgrade();

        void unlock_upgrade_and_lock();
        void unlock_and_lock_upgrade();
        void unlock_and_lock_shared();
        void unlock_upgrade_and_lock_shared();
    #endif

    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
        bool timed_lock_shared(system_time const& timeout);
        bool timed_lock(system_time const& timeout);
    #endif

    };

The class `boost::shared_mutex` provides an implementation of a multiple-reader / single-writer mutex. It implements the `SharedLockable` concept.

Multiple concurrent calls to `lock()`, `try_lock()`, ``try_lock_for`()`, ``try_lock_until`()`, `timed_lock()`, `lock_shared()`, ``try_lock_shared_for`()`, ``try_lock_shared_until`()`, `try_lock_shared()` and `timed_lock_shared()` are permitted.

Note the the lack of reader-writer priority policies in shared_mutex. This is due to an algorithm credited to Alexander Terekhov which lets the OS decide which thread is the next to get the lock without caring whether a unique lock or shared lock is being sought. This results in a complete lack of reader or writer starvation. It is simply fair.

#### Class `upgrade_mutex`

    #include <boost/thread/shared_mutex.hpp>

    class upgrade_mutex
    {
    public:
        upgrade_mutex(upgrade_mutex const&) = delete;
        upgrade_mutex& operator=(upgrade_mutex const&) = delete;

        upgrade_mutex();
        ~upgrade_mutex();

        void lock_shared();
        bool try_lock_shared();
        template <class Rep, class Period>
        bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
        template <class Clock, class Duration>
        bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
        void unlock_shared();

        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();

        void lock_upgrade();
        template <class Rep, class Period>
        bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time);
        template <class Clock, class Duration>
        bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time);
        void unlock_upgrade();

        // Shared <-> Exclusive

    #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
        bool try_unlock_shared_and_lock();
        template <class Rep, class Period>
        bool try_unlock_shared_and_lock_for(const chrono::duration<Rep, Period>& rel_time);
        template <class Clock, class Duration>
        bool try_unlock_shared_and_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    #endif
        void unlock_and_lock_shared();

        // Shared <-> Upgrade

    #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
        bool try_unlock_shared_and_lock_upgrade();
        template <class Rep, class Period>
        bool try_unlock_shared_and_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time);
        template <class Clock, class Duration>
        bool try_unlock_shared_and_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time);
    #endif
        void unlock_upgrade_and_lock_shared();

        // Upgrade <-> Exclusive

        void unlock_upgrade_and_lock();
    #if    defined(BOOST_THREAD_PLATFORM_PTHREAD)
        || defined(BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN)
        bool try_unlock_upgrade_and_lock();
        template <class Rep, class Period>
        bool try_unlock_upgrade_and_lock_for(const chrono::duration<Rep, Period>& rel_time);
        template <class Clock, class Duration>
        bool try_unlock_upgrade_and_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    #endif
        void unlock_and_lock_upgrade();
    };

The class `boost::upgrade_mutex` provides an implementation of a multiple-reader / single-writer mutex. It implements the `UpgradeLockable` concept.

Multiple concurrent calls to `lock()`, `try_lock()`, ``try_lock_for`()`, ``try_lock_until`()`, `timed_lock()`, `lock_shared()`, ``try_lock_shared_for`()`, ``try_lock_shared_until`()`, `try_lock_shared()` and `timed_lock_shared()` are permitted.

### Condition Variables

##### Synopsis

    namespace boost
    {
      enum class cv_status;
      {
        no_timeout,
        timeout
      };
      class condition_variable;
      class condition_variable_any;
      void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
    }

The classes `condition_variable` and `condition_variable_any` provide a mechanism for one thread to wait for notification from another thread that a particular condition has become true. The general usage pattern is that one thread locks a mutex and then calls `wait` on an instance of `condition_variable` or `condition_variable_any`. When the thread is woken from the wait, then it checks to see if the appropriate condition is now true, and continues if so. If the condition is not true, then the thread then calls `wait` again to resume waiting. In the simplest case, this condition is just a boolean variable:

    boost::condition_variable cond;
    boost::mutex mut;
    bool data_ready;

    void process_data();

    void wait_for_data_to_process()
    {
        boost::unique_lock<boost::mutex> lock(mut);
        while(!data_ready)
        {
            cond.wait(lock);
        }
        process_data();
    }

Notice that the `lock` is passed to `wait`: `wait` will atomically add the thread to the set of threads waiting on the condition variable, and unlock the mutex. When the thread is woken, the mutex will be locked again before the call to `wait` returns. This allows other threads to acquire the mutex in order to update the shared data, and ensures that the data associated with the condition is correctly synchronized.

In the mean time, another thread sets the condition to `true`, and then calls either `notify_one` or `notify_all` on the condition variable to wake one waiting thread or all the waiting threads respectively.

    void retrieve_data();
    void prepare_data();

    void prepare_data_for_processing()
    {
        retrieve_data();
        prepare_data();
        {
            boost::lock_guard<boost::mutex> lock(mut);
            data_ready=true;
        }
        cond.notify_one();
    }

Note that the same mutex is locked before the shared data is updated, but that the mutex does not have to be locked across the call to `notify_one`.

This example uses an object of type `condition_variable`, but would work just as well with an object of type `condition_variable_any`: `condition_variable_any` is more general, and will work with any kind of lock or mutex, whereas `condition_variable` requires that the lock passed to `wait` is an instance of `boost::unique_lock<boost::mutex>`. This enables `condition_variable` to make optimizations in some cases, based on the knowledge of the mutex type; `condition_variable_any` typically has a more complex implementation than `condition_variable`.

#### Class `condition_variable`

    //#include <boost/thread/condition_variable.hpp>

    namespace boost
    {
        class condition_variable
        {
        public:
            condition_variable();
            ~condition_variable();

            void notify_one() noexcept;
            void notify_all() noexcept;

            void wait(boost::unique_lock<boost::mutex>& lock);

            template<typename predicate_type>
            void wait(boost::unique_lock<boost::mutex>& lock,predicate_type predicate);

            template <class Clock, class Duration>
            typename cv_status::type
            wait_until(
                unique_lock<mutex>& lock,
                const chrono::time_point<Clock, Duration>& t);

            template <class Clock, class Duration, class Predicate>
            bool
            wait_until(
                unique_lock<mutex>& lock,
                const chrono::time_point<Clock, Duration>& t,
                Predicate pred);

            template <class Rep, class Period>
            typename cv_status::type
            wait_for(
                unique_lock<mutex>& lock,
                const chrono::duration<Rep, Period>& d);

            template <class Rep, class Period, class Predicate>
            bool
            wait_for(
                unique_lock<mutex>& lock,
                const chrono::duration<Rep, Period>& d,
                Predicate pred);

        #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time);
            template<typename duration_type>
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time);
            template<typename predicate_type>
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time,predicate_type predicate);
            template<typename duration_type,typename predicate_type>
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time,predicate_type predicate);
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time);

            template<typename predicate_type>
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate);
        #endif

        };
    }

##### `condition_variable()`

Effects:

  Constructs an object of class `condition_variable`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `~condition_variable()`

Precondition:

  All threads waiting on `*this` have been notified by a call to `notify_one` or `notify_all` (though the respective calls to `wait` or `timed_wait` need not have returned).

Effects:

  Destroys the object.

Throws:

  Nothing.

##### `void notify_one()`

Effects:

  If any threads are currently blocked waiting on `*this` in a call to `wait` or `timed_wait`, unblocks one of those threads.

Throws:

  Nothing.

##### `void notify_all()`

Effects:

  If any threads are currently blocked waiting on `*this` in a call to `wait` or `timed_wait`, unblocks all of those threads.

Throws:

  Nothing.

##### `void wait(boost::unique_lock<boost::mutex>& lock)`

Precondition:

  `lock` is locked by the current thread, and either no other thread is currently waiting on `*this`, or the execution of the `mutex()` member function on the `lock` objects supplied in the calls to `wait` or `timed_wait` in all the threads currently waiting on `*this` would return the same value as `lock->mutex()` for this call to `wait`.

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template<typename predicate_type> void wait(boost::unique_lock<boost::mutex>& lock, predicate_type pred)`

Effects:

  As-if

      while(!pred())
      {
          wait(lock);
      }

##### `bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time)`

Precondition:

  `lock` is locked by the current thread, and either no other thread is currently waiting on `*this`, or the execution of the `mutex()` member function on the `lock` objects supplied in the calls to `wait` or `timed_wait` in all the threads currently waiting on `*this` would return the same value as `lock->mutex()` for this call to `wait`.

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, when the time as reported by `boost::get_system_time()` would be equal to or later than the specified `abs_time`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `false` if the call is returning because the time specified by `abs_time` was reached, `true` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template<typename duration_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time)`

Precondition:

  `lock` is locked by the current thread, and either no other thread is currently waiting on `*this`, or the execution of the `mutex()` member function on the `lock` objects supplied in the calls to `wait` or `timed_wait` in all the threads currently waiting on `*this` would return the same value as `lock->mutex()` for this call to `wait`.

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, after the period of time indicated by the `rel_time` argument has elapsed, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `false` if the call is returning because the time period specified by `rel_time` has elapsed, `true` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

| Note
The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.

##### `template<typename predicate_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock, boost::system_time const& abs_time, predicate_type pred)`

Effects:

  As-if

      while(!pred())
      {
          if(!timed_wait(lock,abs_time))
          {
              return pred();
          }
      }
      return true;

##### `template <class Clock, class Duration> cv_status wait_until(boost::unique_lock<boost::mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time)`

Precondition:

  `lock` is locked by the current thread, and either no other thread is currently waiting on `*this`, or the execution of the `mutex()` member function on the `lock` objects supplied in the calls to `wait` or `wait_for` or `wait_until` in all the threads currently waiting on `*this` would return the same value as `lock->mutex()` for this call to `wait`.

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, when the time as reported by `Clock::now()` would be equal to or later than the specified `abs_time`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `cv_status::no_timeout` if the call is returning because the time specified by `abs_time` was reached, `cv_status::timeout` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template <class Rep, class Period> cv_status wait_for(boost::unique_lock<boost::mutex>& lock, const chrono::duration<Rep, Period>& rel_time)`

Precondition:

  `lock` is locked by the current thread, and either no other thread is currently waiting on `*this`, or the execution of the `mutex()` member function on the `lock` objects supplied in the calls to `wait` or `wait_until` or `wait_for` in all the threads currently waiting on `*this` would return the same value as `lock->mutex()` for this call to `wait`.

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, after the period of time indicated by the `rel_time` argument has elapsed, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `cv_status::no_timeout` if the call is returning because the time period specified by `rel_time` has elapsed, `cv_status::timeout` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

| Note
The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.

##### `template <class Clock, class Duration, class Predicate> bool wait_until(boost::unique_lock<boost::mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred)`

Effects:

  As-if

      while(!pred())
      {
          if(!wait_until(lock,abs_time))
          {
              return pred();
          }
      }
      return true;

##### `template <class Rep, class Period, class Predicate> bool wait_for(boost::unique_lock<boost::mutex>& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred)`

Effects:

  As-if

      while(!pred())
      {
          if(!wait_for(lock,rel_time))
          {
              return pred();
          }
      }
      return true;

#### Class `condition_variable_any`

    //#include <boost/thread/condition_variable.hpp>

    namespace boost
    {
        class condition_variable_any
        {
        public:
            condition_variable_any();
            ~condition_variable_any();

            void notify_one();
            void notify_all();

            template<typename lock_type>
            void wait(lock_type& lock);

            template<typename lock_type,typename predicate_type>
            void wait(lock_type& lock,predicate_type predicate);

            template <class lock_type, class Clock, class Duration>
            cv_status wait_until(
                lock_type& lock,
                const chrono::time_point<Clock, Duration>& t);

            template <class lock_type, class Clock, class Duration, class Predicate>
            bool wait_until(
                lock_type& lock,
                const chrono::time_point<Clock, Duration>& t,
                Predicate pred);

            template <class lock_type, class Rep, class Period>
            cv_status wait_for(
                lock_type& lock,
                const chrono::duration<Rep, Period>& d);

            template <class lock_type, class Rep, class Period, class Predicate>
            bool wait_for(
                lock_type& lock,
                const chrono::duration<Rep, Period>& d,
                Predicate pred);

        #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
            template<typename lock_type>
            bool timed_wait(lock_type& lock,boost::system_time const& abs_time);
            template<typename lock_type,typename duration_type>
            bool timed_wait(lock_type& lock,duration_type const& rel_time);
            template<typename lock_type,typename predicate_type>
            bool timed_wait(lock_type& lock,boost::system_time const& abs_time,predicate_type predicate);
            template<typename lock_type,typename duration_type,typename predicate_type>
            bool timed_wait(lock_type& lock,duration_type const& rel_time,predicate_type predicate);
            template<typename lock_type>
            bool timed_wait(lock_type>& lock,boost::xtime const& abs_time);
            template<typename lock_type,typename predicate_type>
            bool timed_wait(lock_type& lock,boost::xtime const& abs_time,predicate_type predicate);
        #endif
        };
    }

##### `condition_variable_any()`

Effects:

  Constructs an object of class `condition_variable_any`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `~condition_variable_any()`

Precondition:

  All threads waiting on `*this` have been notified by a call to `notify_one` or `notify_all` (though the respective calls to `wait` or `timed_wait` need not have returned).

Effects:

  Destroys the object.

Throws:

  Nothing.

##### `void notify_one()`

Effects:

  If any threads are currently blocked waiting on `*this` in a call to `wait` or `timed_wait`, unblocks one of those threads.

Throws:

  Nothing.

##### `void notify_all()`

Effects:

  If any threads are currently blocked waiting on `*this` in a call to `wait` or `timed_wait`, unblocks all of those threads.

Throws:

  Nothing.

##### `template<typename lock_type> void wait(lock_type& lock)`

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template<typename lock_type,typename predicate_type> void wait(lock_type& lock, predicate_type pred)`

Effects:

  As-if

      while(!pred())
      {
          wait(lock);
      }

##### `template<typename lock_type> bool timed_wait(lock_type& lock,boost::system_time const& abs_time)`

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, when the time as reported by `boost::get_system_time()` would be equal to or later than the specified `abs_time`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `false` if the call is returning because the time specified by `abs_time` was reached, `true` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template<typename lock_type,typename duration_type> bool timed_wait(lock_type& lock,duration_type const& rel_time)`

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, after the period of time indicated by the `rel_time` argument has elapsed, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `false` if the call is returning because the time period specified by `rel_time` has elapsed, `true` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

| Note
The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.

##### `template<typename lock_type,typename predicate_type> bool timed_wait(lock_type& lock, boost::system_time const& abs_time, predicate_type pred)`

Effects:

  As-if

      while(!pred())
      {
          if(!timed_wait(lock,abs_time))
          {
              return pred();
          }
      }
      return true;

##### `template <class lock_type, class Clock, class Duration> cv_status wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& abs_time)`

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, when the time as reported by `Clock::now()` would be equal to or later than the specified `abs_time`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `cv_status::timeout` if the call is returning because the time specified by `abs_time` was reached, `cv_status::no_timeout` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template <class lock_type, class Rep, class Period> cv_status wait_for(lock_type& lock, const chrono::duration<Rep, Period>& rel_time)`

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, after the period of time indicated by the `rel_time` argument has elapsed, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `cv_status::timeout` if the call is returning because the time specified by `abs_time` was reached, `cv_status::no_timeout` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

| Note
The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.

##### `template <class lock_type, class Clock, class Duration, class Predicate> bool wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred)`

Effects:

  As-if

      while(!pred())
      {
          if(!wait_until(lock,abs_time))
          {
              return pred();
          }
      }
      return true;

##### `template <class lock_type, class Rep, class Period, class Predicate> bool wait_until(lock_type& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred)`

Effects:

  As-if

      while(!pred())
      {
          if(!wait_for(lock,rel_time))
          {
              return pred();
          }
      }
      return true;

#### Typedef `condition` DEPRECATED V3

    // #include <boost/thread/condition.hpp>
    namespace boost
    {

      typedef condition_variable_any condition;

    }

The typedef `condition` is provided for backwards compatibility with previous boost releases.

#### Non-member Function `notify_all_at_thread_exit`()

    // #include <boost/thread/condition_variable.hpp>

    namespace boost
    {
      void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
    }

Requires:

  `lk` is locked by the calling thread and either no other thread is waiting on `cond`, or `lk.mutex()` returns the same value for each of the lock arguments supplied by all concurrently waiting (via `wait`, `wait_for`, or `wait_until`) threads.

Effects:

  transfers ownership of the lock associated with `lk` into internal storage and schedules `cond` to be notified when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed. This notification shall be as if

      lk.unlock();
      cond.notify_all();

### One-time Initialization

    #include <boost/thread/once.hpp>

    namespace boost
    {
      struct once_flag;
      template<typename Callable>
      void call_once(once_flag& flag,Callable func);

    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
      void call_once(void (*func)(),once_flag& flag);
    #endif

    }

`boost::call_once` provides a mechanism for ensuring that an initialization routine is run exactly once without data races or deadlocks.

#### Typedef `once_flag`

    #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
    struct once_flag
    {
      constexprr once_flag() noexcept;
      once_flag(const once_flag&) = delete;
      once_flag& operator=(const once_flag&) = delete;
    };
    #else
    typedef platform-specific-type once_flag;
    #define BOOST_ONCE_INIT platform-specific-initializer
    #endif

Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT` if BOOST_THREAD_PROVIDES_ONCE_CXX11 is not defined

    boost::once_flag f=BOOST_ONCE_INIT;

#### Non-member function `call_once`

    template<typename Callable>
    void call_once(once_flag& flag,Callable func);

Requires:

  `Callable` is `CopyConstructible`. Copying `func` shall have no side effects, and the effect of calling the copy shall be equivalent to calling the original.

Effects:

  Calls to `call_once` on the same `once_flag` object are serialized. If there has been no prior effective `call_once` on the same `once_flag` object, the argument `func` (or a copy thereof) is called as-if by invoking `func()`, and the invocation of `call_once` is effective if and only if `func()` returns without exception. If an exception is thrown, the exception is propagated to the caller. If there has been a prior effective `call_once` on the same `once_flag` object, the `call_once` returns without invoking `func`.

Synchronization:

  The completion of an effective `call_once` invocation on a `once_flag` object, synchronizes with all subsequent `call_once` invocations on the same `once_flag` object.

Throws:

  `thread_resource_error` when the effects cannot be achieved. or any exception propagated from `func`.

Note:

  The function passed to `call_once` must not also call `call_once` passing the same `once_flag` object. This may cause deadlock, or invoking the passed function a second time. The alternative is to allow the second call to return immediately, but that assumes the code knows it has been called recursively, and can proceed even though the call to `call_once` didn't actually call the function, in which case it could also avoid calling `call_once` recursively.

    void call_once(void (*func)(),once_flag& flag);

This second overload is provided for backwards compatibility. The effects of `call_once(func,flag)` shall be the same as those of `call_once(flag,func)`.

### Barriers

A barrier is a simple concept. Also known as a rendezvous, it is a synchronization point between multiple threads. The barrier is configured for a particular number of threads (`n`), and as threads reach the barrier they must wait until all `n` threads have arrived. Once the `n`-th thread has reached the barrier, all the waiting threads can proceed, and the barrier is reset.

#### Class `barrier`

    #include <boost/thread/barrier.hpp>

    class barrier
    {
    public:
        barrier(unsigned int count);
        ~barrier();

        bool wait();
    };

Instances of `boost::barrier` are not copyable or movable.

###### Constructor

    barrier(unsigned int count);

Effects:

  Construct a barrier for `count` threads.

Throws:

  `boost::thread_resource_error` if an error occurs.

###### Destructor

    ~barrier();

Precondition:

  No threads are waiting on `*this`.

Effects:

  Destroys `*this`.

Throws:

  Nothing.

###### Member function `wait`

    bool wait();

Effects:

  Block until `count` threads have called `wait` on `*this`. When the `count`-th thread calls `wait`, all waiting threads are unblocked, and the barrier is reset.

Returns:

  `true` for exactly one thread from each batch of waiting threads, `false` otherwise.

Throws:

  `boost::thread_resource_error` if an error occurs.

### Futures

#### Overview

The futures library provides a means of handling synchronous future values, whether those values are generated by another thread, or on a single thread in response to external stimuli, or on-demand.

This is done through the provision of four class templates: `future` and `boost::shared_future` which are used to retrieve the asynchronous results, and `boost::promise` and `boost::packaged_task` which are used to generate the asynchronous results.

An instance of `future` holds the one and only reference to a result. Ownership can be transferred between instances using the move constructor or move-assignment operator, but at most one instance holds a reference to a given asynchronous result. When the result is ready, it is returned from `boost::future<R>::get()` by rvalue-reference to allow the result to be moved or copied as appropriate for the type.

On the other hand, many instances of `boost::shared_future` may reference the same result. Instances can be freely copied and assigned, and `boost::shared_future<R>::get()` returns a `const` reference so that multiple calls to `boost::shared_future<R>::get()` are safe. You can move an instance of `future` into an instance of `boost::shared_future`, thus transferring ownership of the associated asynchronous result, but not vice-versa.

You can wait for futures either individually or with one of the `boost::wait_for_any()` and `boost::wait_for_all()` functions.

#### Creating asynchronous values

You can set the value in a future with either a `boost::promise` or a `boost::packaged_task`. A `boost::packaged_task` is a callable object that wraps a function or callable object. When the packaged task is invoked, it invokes the contained function in turn, and populates a future with the return value. This is an answer to the perennial question: "how do I return a value from a thread?": package the function you wish to run as a `boost::packaged_task` and pass the packaged task to the thread constructor. The future retrieved from the packaged task can then be used to obtain the return value. If the function throws an exception, that is stored in the future in place of the return value.

    int calculate_the_answer_to_life_the_universe_and_everything()
    {
        return 42;
    }

    boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
    boost:: future<int> fi=pt.get_future();

    boost::thread task(boost::move(pt)); // launch task on a thread

    fi.wait(); // wait for it to finish

    assert(fi.is_ready());
    assert(fi.has_value());
    assert(!fi.has_exception());
    assert(fi.get_state()==boost::future_state::ready);
    assert(fi.get()==42);

A `boost::promise` is a bit more low level: it just provides explicit functions to store a value or an exception in the associated future. A promise can therefore be used where the value may come from more than one possible source, or where a single operation may produce multiple values.

    boost::promise<int> pi;
    boost:: future<int> fi;
    fi=pi.get_future();

    pi.set_value(42);

    assert(fi.is_ready());
    assert(fi.has_value());
    assert(!fi.has_exception());
    assert(fi.get_state()==boost::future_state::ready);
    assert(fi.get()==42);

#### Wait Callbacks and Lazy Futures

Both `boost::promise` and `boost::packaged_task` support wait callbacks that are invoked when a thread blocks in a call to `wait()` or `timed_wait()` on a future that is waiting for the result from the `boost::promise` or `boost::packaged_task`, in the thread that is doing the waiting. These can be set using the `set_wait_callback()` member function on the `boost::promise` or `boost::packaged_task` in question.

This allows lazy futures where the result is not actually computed until it is needed by some thread. In the example below, the call to `f.get()` invokes the callback `invoke_lazy_task`, which runs the task to set the value. If you remove the call to `f.get()`, the task is not ever run.

    int calculate_the_answer_to_life_the_universe_and_everything()
    {
        return 42;
    }

    void invoke_lazy_task(boost::packaged_task<int>& task)
    {
        try
        {
            task();
        }
        catch(boost::task_already_started&)
        {}
    }

    int main()
    {
        boost::packaged_task<int> task(calculate_the_answer_to_life_the_universe_and_everything);
        task.set_wait_callback(invoke_lazy_task);
        boost:: future<int> f(task.get_future());

        assert(f.get()==42);
    }

#### Futures Reference

    //#include <boost/thread/futures.hpp>

    namespace boost
    {
    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
      namespace future_state
      {
        enum state {uninitialized, waiting, ready, moved};
      }
    #endif

      enum class future_errc
      {
        broken_promise,
        future_already_retrieved,
        promise_already_satisfied,
        no_state
      };

      enum class launch
      {
        async = unspecified,
        deferred = unspecified,
        any = async | deferred
      };

      enum class future_status {
        ready,  timeout, deferred
      };

      namespace system
      {
        template <>
        struct is_error_code_enum<future_errc> : public true_type {};

        error_code make_error_code(future_errc e);

        error_condition make_error_condition(future_errc e);
      }

      const system::error_category& future_category();

      class future_error;

      template <typename R>
      class promise;

      template <typename R>
      void swap(promise<R>& x, promise<R>& y) noexcept;

      namespace container {
        template <class R, class Alloc>
        struct uses_allocator<promise<R>, Alloc>:: true_type;
      }

      template <typename R>
      class future;

      template <typename R>
      class shared_future;

      template <typename R>
      class packaged_task;
      template <class R> void swap(packaged_task<R>&, packaged_task<R>&) noexcept;

      template <class R, class Alloc>
      struct uses_allocator<packaged_task <R>, Alloc>;

      template <class F>
      future<typename result_of<typename decay<F>::type()>::type>
      async(F f);
      template <class F>
      future<typename result_of<typename decay<F>::type()>::type>
      async(launch policy, F f);

      // template <class F, class... Args>
      // future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
      // async(F&& f, Args&&... args); // NOT YET IMPLEMENTED
      // template <class F, class... Args>
      // future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
      // async(launch policy, F&& f, Args&&... args); // NOT YET IMPLEMENTED

      template<typename Iterator>
      void wait_for_all(Iterator begin,Iterator end); // EXTENSION

      template<typename F1,typename... FS>
      void wait_for_all(F1& f1,Fs&... fs); // EXTENSION

      template<typename Iterator>
      Iterator wait_for_any(Iterator begin,Iterator end);

      template<typename F1,typename... Fs>
      unsigned wait_for_any(F1& f1,Fs&... fs);

##### Enumeration `state`

    namespace future_state
    {
      enum state {uninitialized, waiting, ready, moved};
    }

##### Enumeration `future_errc`

    enum class future_errc
    {
      broken_promise,
      future_already_retrieved,
      promise_already_satisfied,
      no_state
    }

##### Enumeration `launch`

    enum class launch
    {
      async = unspecified,
      deferred = unspecified,
      any = async | deferred
    };

The enum type launch is a bitmask type with launch::async and launch::deferred denoting individual bits.

##### Specialization `is_error_code_enum<future_errc>`

    namespace system
    {
      template <>
      struct is_error_code_enum<future_errc> : public true_type {};

    }

##### Non-member function `make_error_code()`

    namespace system
    {
      error_code make_error_code(future_errc e);
    }

Returns:

  `error_code(static_cast<int>(e), future_category())`.

##### Non-member function `make_error_condition()`

    namespace system
    {
      error_condition make_error_condition(future_errc e);
    }

Returns:

  `error_condition(static_cast<int>(e), future_category())`.

##### Non-member function `future_category()`

    const system::error_category& future_category();

Returns:

  A reference to an object of a type derived from class error_category.

Notes:

  The object's `default_error_condition` and equivalent virtual functions behave as specified for the class `system::error_category`. The object's `name` virtual function returns a pointer to the string "future".

##### Class `future_error`

    class future_error
        : public std::logic_error
    {
    public:
        future_error(system::error_code ec);

        const system::error_code& code() const no_except;
    };

###### Constructor

    future_error(system::error_code ec);

Effects:

  Constructs a future_error.

Postconditions:

  `code()==ec`

Throws:

  Nothing.

###### Member function `code()`

    const system::error_code& code() const no_except;

Returns:

  The value of `ec` that was passed to the object's constructor.

##### Enumeration `future_status`

    enum class future_status {
      ready,  timeout, deferred
    };

##### `future` class template

    template <typename R>
    class  future
    {

    public:
       future( future & rhs);// = delete;
       future& operator=( future& rhs);// = delete;

       future() noexcept;
      ~ future();

      // move support
       future( future && other) noexcept;
       future& operator=( future && other) noexcept;
      shared_future<R> share();

      void swap( future& other) noexcept; // EXTENSION

      // retrieving the value
      R&& get();

      // functions to check state
      bool valid() const;
      bool is_ready() const; // EXTENSION
      bool has_exception() const; // EXTENSION
      bool has_value() const; // EXTENSION

      // waiting for the result to be ready
      void wait() const;
      template <class Rep, class Period>
      future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
      template <class Clock, class Duration>
      future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
      template<typename Duration>
      bool timed_wait(Duration const& rel_time) const;
      bool timed_wait_until(boost::system_time const& abs_time) const;
    #endif
    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
      typedef future_state::state state;
      state get_state() const;
    #endif
    };

###### Default Constructor

     future();

Effects:

  Constructs an uninitialized `future`.

Postconditions:

  `this->is_ready` returns `false`. `this->get_state()` returns `boost::future_state::uninitialized`.

Throws:

  Nothing.

###### Destructor

    ~ future();

Effects:

  Destroys `*this`.

Throws:

  Nothing.

###### Move Constructor

     future( future && other);

Effects:

  Constructs a new `future`, and transfers ownership of the asynchronous result associated with `other` to `*this`.

Postconditions:

  `this->get_state()` returns the value of `other->get_state()` prior to the call. `other->get_state()` returns `boost::future_state::uninitialized`. If `other` was associated with an asynchronous result, that result is now associated with `*this`. `other` is not associated with any asynchronous result.

Throws:

  Nothing.

Notes:

  If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

###### Move Assignment Operator

     future& operator=( future && other);

Effects:

  Transfers ownership of the asynchronous result associated with `other` to `*this`.

Postconditions:

  `this->get_state()` returns the value of `other->get_state()` prior to the call. `other->get_state()` returns `boost::future_state::uninitialized`. If `other` was associated with an asynchronous result, that result is now associated with `*this`. `other` is not associated with any asynchronous result. If `*this` was associated with an asynchronous result prior to the call, that result no longer has an associated `future` instance.

Throws:

  Nothing.

Notes:

  If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

###### Member function `swap()`

    void swap( future & other) no_except;

Effects:

  Swaps ownership of the asynchronous results associated with `other` and `*this`.

Postconditions:

  `this->get_state()` returns the value of `other->get_state()` prior to the call. `other->get_state()` returns the value of `this->get_state()` prior to the call. If `other` was associated with an asynchronous result, that result is now associated with `*this`, otherwise `*this` has no associated result. If `*this` was associated with an asynchronous result, that result is now associated with `other`, otherwise `other` has no associated result.

Throws:

  Nothing.

###### Member function `get()`

    R&& get();
    R&  future<R&>::get();
    void  future<void>::get();

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready as-if by a call to `boost::future<R>::wait()`, and retrieves the result (whether that is a value or an exception).

Returns:

  If the result type `R` is a reference, returns the stored reference. If `R` is `void`, there is no return value. Otherwise, returns an rvalue-reference to the value stored in the asynchronous result.

Postconditions:

  `this->is_ready()` returns `true`. `this->get_state()` returns `boost::future_state::ready`.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception stored in the asynchronous result in place of a value.

Notes:

  `get()` is an interruption point.

###### Member function `wait()`

    void wait();

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  `this->is_ready()` returns `true`. `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `wait()` is an interruption point.

###### Member function `timed_wait()`

    template<typename Duration>
    bool timed_wait(Duration const& wait_duration);

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by `wait_duration` has elapsed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

  `true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has elapsed, `false` otherwise.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  If this call returned `true`, then `this->is_ready()` returns `true` and `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `timed_wait()` is an interruption point. `Duration` must be a type that meets the Boost.DateTime time duration requirements.

###### Member function `timed_wait()`

    bool timed_wait(boost::system_time const& wait_timeout);

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by `wait_timeout` has passed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

  `true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has passed, `false` otherwise.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  If this call returned `true`, then `this->is_ready()` returns `true` and `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `timed_wait()` is an interruption point.

###### Member function `wait_for()`

    template <class Rep, class Period>
    future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by `wait_duration` has elapsed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

  - `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet)

  - `future_status::ready` if the shared state is ready.

  - `future_status::timeout` if the function is returning because the relative timeout specified by `rel_time` has expired.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  If this call returned `true`, then `this->is_ready()` returns `true` and `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `wait_for()` is an interruption point. `Duration` must be a type that meets the Boost.DateTime time duration requirements.

###### Member function `wait_until()`

    template <class Clock, class Duration>
    future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by `wait_timeout` has passed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

  - `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet)

  - `future_status::ready` if the shared state is ready.

  - `future_status::timeout` if the function is returning because the absolute timeout specified by `absl_time` has reached.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  If this call returned `true`, then `this->is_ready()` returns `true` and `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `wait_until()` is an interruption point.

###### Member function `valid()`

    bool valid() const;

Returns:

  `true` if `*this` is associated with an asynchronous result, `false` otherwise.

Throws:

  Nothing.

###### Member function `is_ready()` EXTENSION

    bool is_ready() const;

Returns:

  `true` if `*this` is associated with an asynchronous result and that result is ready for retrieval, `false` otherwise.

Throws:

  Nothing.

###### Member function `has_value()` EXTENSION

    bool has_value() const;

Returns:

  `true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a stored value, `false` otherwise.

Throws:

  Nothing.

###### Member function `has_exception()` EXTENSION

    bool has_exception() const;

Returns:

  `true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a stored exception, `false` otherwise.

Throws:

  Nothing.

###### Member function `get_state()`

    future_state::state get_state();

Effects:

  Determine the state of the asynchronous result associated with `*this`, if any.

Returns:

  `boost::future_state::uninitialized` if `*this` is not associated with an asynchronous result. `boost::future_state::ready` if the asynchronous result associated with `*this` is ready for retrieval, `boost::future_state::waiting` otherwise.

Throws:

  Nothing.

##### `shared_future` class template

    template <typename R>
    class shared_future
    {
    public:
      typedef future_state::state state; // EXTENSION

      shared_future() noexcept;
      ~shared_future();

      // copy support
      shared_future(shared_future const& other);
      shared_future& operator=(shared_future const& other);

      // move support
      shared_future(shared_future && other) noexcept;
      shared_future( future<R> && other) noexcept;
      shared_future& operator=(shared_future && other) noexcept;
      shared_future& operator=( future<R> && other) noexcept;

      void swap(shared_future& other);

      // retrieving the value
      R get();

      // functions to check state, and wait for ready
      bool valid() const noexcept;
      bool is_ready() const noexcept; // EXTENSION
      bool has_exception() const noexcept; // EXTENSION
      bool has_value() const noexcept; // EXTENSION

      // waiting for the result to be ready
      void wait() const;
      template <class Rep, class Period>
      future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
      template <class Clock, class Duration>
      future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
      template<typename Duration>
      bool timed_wait(Duration const& rel_time) const;
      bool timed_wait_until(boost::system_time const& abs_time) const;
    #endif
    #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
      state get_state() const noexcept;
    #endif
    };

###### Default Constructor

    shared_future();

Effects:

  Constructs an uninitialized shared_future.

Postconditions:

  `this->is_ready` returns `false`. `this->get_state()` returns `boost::future_state::uninitialized`.

Throws:

  Nothing.

###### Member function `get()`

    const R& get();

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready as-if by a call to `boost::shared_future<R>::wait()`, and returns a `const` reference to the result.

Returns:

  If the result type `R` is a reference, returns the stored reference. If `R` is `void`, there is no return value. Otherwise, returns a `const` reference to the value stored in the asynchronous result.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted.

Notes:

  `get()` is an interruption point.

###### Member function `wait()`

    void wait();

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  `this->is_ready()` returns `true`. `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `wait()` is an interruption point.

###### Member function `timed_wait()`

    template<typename Duration>
    bool timed_wait(Duration const& wait_duration);

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by `wait_duration` has elapsed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

  `true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has elapsed, `false` otherwise.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  If this call returned `true`, then `this->is_ready()` returns `true` and `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `timed_wait()` is an interruption point. `Duration` must be a type that meets the Boost.DateTime time duration requirements.

###### Member function `timed_wait()`

    bool timed_wait(boost::system_time const& wait_timeout);

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by `wait_timeout` has passed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

  `true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has passed, `false` otherwise.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  If this call returned `true`, then `this->is_ready()` returns `true` and `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `timed_wait()` is an interruption point.

###### Member function `wait_for()`

    template <class Rep, class Period>
    future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by `wait_duration` has elapsed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

  - `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet)

  - `future_status::ready` if the shared state is ready.

  - `future_status::timeout` if the function is returning because the relative timeout specified by `rel_time` has expired.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  If this call returned `true`, then `this->is_ready()` returns `true` and `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `timed_wait()` is an interruption point. `Duration` must be a type that meets the Boost.DateTime time duration requirements.

###### Member function `wait_until()`

    template <class Clock, class Duration>
    future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

Effects:

  If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by `wait_timeout` has passed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

  - `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet)

  - `future_status::ready` if the shared state is ready.

  - `future_status::timeout` if the function is returning because the absolute timeout specified by `absl_time` has reached.

Throws:

  `boost::future_uninitialized` if `*this` is not associated with an asynchronous result. `boost::thread_interrupted` if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the wait callback if such a callback is called.

Postconditions:

  If this call returned `true`, then `this->is_ready()` returns `true` and `this->get_state()` returns `boost::future_state::ready`.

Notes:

  `timed_wait()` is an interruption point.

###### Member function `valid()`

    bool valid() const;

Returns:

  `true` if `*this` is associated with an asynchronous result, `false` otherwise.

Throws:

  Nothing.

###### Member function `is_ready()` EXTENSION

    bool is_ready() const;

Returns:

  `true` if `*this` is associated with an asynchronous result, and that result is ready for retrieval, `false` otherwise.

Throws:

  Nothing.

###### Member function `has_value()` EXTENSION

    bool has_value() const;

Returns:

  `true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a stored value, `false` otherwise.

Throws:

  Nothing.

###### Member function `has_exception()` EXTENSION

    bool has_exception() const;

Returns:

  `true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a stored exception, `false` otherwise.

Throws:

  Nothing.

###### Member function `get_state()`

    future_state::state get_state();

Effects:

  Determine the state of the asynchronous result associated with `*this`, if any.

Returns:

  `boost::future_state::uninitialized` if `*this` is not associated with an asynchronous result. `boost::future_state::ready` if the asynchronous result associated with `*this` is ready for retrieval, `boost::future_state::waiting` otherwise.

Throws:

  Nothing.

##### `promise` class template

    template <typename R>
    class promise
    {
    public:

      promise();
      template <class Allocator>
      promise(allocator_arg_t, Allocator a);
      promise & operator=(const promise & rhs);// = delete;
      promise(const promise & rhs);// = delete;
      ~promise();

      // Move support
      promise(promise && rhs) noexcept;;
      promise & operator=(promise&& rhs) noexcept;;

      void swap(promise& other) noexcept;
      // Result retrieval
       future<R> get_future();

      // Set the value
      void set_value(R& r);
      void set_value(R&& r);
      void set_exception(boost::exception_ptr e);

      // setting the result with deferred notification
      // void set_value_at_thread_exit(const R& r); // NOT YET IMPLEMENTED
      // void set_value_at_thread_exit(see below); // NOT YET IMPLEMENTED
      // void set_exception_at_thread_exit(exception_ptr p); // NOT YET IMPLEMENTED

      template<typename F>
      void set_wait_callback(F f); // EXTENSION
    };

###### Default Constructor

    promise();

Effects:

  Constructs a new `boost::promise` with no associated result.

Throws:

  Nothing.

###### Allocator Constructor

    template <class Allocator>
    promise(allocator_arg_t, Allocator a);

Effects:

  Constructs a new `boost::promise` with no associated result using the allocator `a`.

Throws:

  Nothing.

Notes:

  Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.

###### Move Constructor

    promise(promise && other);

Effects:

  Constructs a new `boost::promise`, and transfers ownership of the result associated with `other` to `*this`, leaving `other` with no associated result.

Throws:

  Nothing.

Notes:

  If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

###### Move Assignment Operator

    promise& operator=(promise && other);

Effects:

  Transfers ownership of the result associated with `other` to `*this`, leaving `other` with no associated result. If there was already a result associated with `*this`, and that result was not ready, sets any futures associated with that result to ready with a `boost::broken_promise` exception as the result.

Throws:

  Nothing.

Notes:

  If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

###### Destructor

    ~promise();

Effects:

  Destroys `*this`. If there was a result associated with `*this`, and that result is not ready, sets any futures associated with that task to ready with a `boost::broken_promise` exception as the result.

Throws:

  Nothing.

###### Member Function `get_future()`

     future<R> get_future();

Effects:

  If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with `*this`. Returns a `future` associated with the result associated with `*this`.

Throws:

  `boost::future_already_retrieved` if the future associated with the task has already been retrieved. `std::bad_alloc` if any memory necessary could not be allocated.

###### Member Function `set_value()`

    void set_value(R&& r);
    void set_value(const R& r);
    void promise<R&>::set_value(R& r);
    void promise<void>::set_value();

Effects:

  If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with `*this`. Store the value `r` in the asynchronous result associated with `*this`. Any threads blocked waiting for the asynchronous result are woken.

Postconditions:

  All futures waiting on the asynchronous result are ready and `boost::future<R>::has_value()` or `boost::shared_future<R>::has_value()` for those futures shall return `true`.

Throws:

  `boost::promise_already_satisfied` if the result associated with `*this` is already ready. `std::bad_alloc` if the memory required for storage of the result cannot be allocated. Any exception thrown by the copy or move-constructor of `R`.

###### Member Function `set_exception()`

    void set_exception(boost::exception_ptr e);

Effects:

  If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with `*this`. Store the exception `e` in the asynchronous result associated with `*this`. Any threads blocked waiting for the asynchronous result are woken.

Postconditions:

  All futures waiting on the asynchronous result are ready and `boost::future<R>::has_exception()` or `boost::shared_future<R>::has_exception()` for those futures shall return `true`.

Throws:

  `boost::promise_already_satisfied` if the result associated with `*this` is already ready. `std::bad_alloc` if the memory required for storage of the result cannot be allocated.

###### Member Function `set_wait_callback()`

    template<typename F>
    void set_wait_callback(F f);

Preconditions:

  The expression `f(t)` where `t` is a lvalue of type `boost::promise` shall be well-formed. Invoking a copy of `f` shall have the same effect as invoking `f`

Effects:

  Store a copy of `f` with the asynchronous result associated with `*this` as a wait callback. This will replace any existing wait callback store alongside that result. If a thread subsequently calls one of the wait functions on a `future` or `boost::shared_future` associated with this result, and the result is not ready, `f(*this)` shall be invoked.

Throws:

  `std::bad_alloc` if memory cannot be allocated for the required storage.

##### `packaged_task` class template

    template<typename R
      // , class... ArgTypes // NOT YET IMPLEMENTED
    >
    class packaged_task
    {
    public:
      typedef R result_type;

      packaged_task(packaged_task&);// = delete;
      packaged_task& operator=(packaged_task&);// = delete;

      // construction and destruction
      packaged_task() noexcept;

      explicit packaged_task(R(*f)());

      template <class F>
      explicit packaged_task(F&& f);

      template <class F, class Allocator>
      packaged_task(allocator_arg_t, Allocator a, F&& f);

      ~packaged_task()
      {}

      // move support
      packaged_task(packaged_task&& other) noexcept;
      packaged_task& operator=(packaged_task&& other) noexcept;

      void swap(packaged_task& other) noexcept;

      bool valid() const noexcept;
      // result retrieval
       future<R> get_future();

      // execution
      void operator()();
      // void operator()(ArgTypes... );  // NOT YET IMPLEMENTED
      // void make_ready_at_thread_exit(ArgTypes...); // NOT YET IMPLEMENTED

      void reset();
      template<typename F>
      void set_wait_callback(F f);  // EXTENSION
    };

###### Task Constructor

    packaged_task(R(*f)());

    template<typename F>
    packaged_task(F&&f);

Preconditions:

  `f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same as invoking `f`.

Effects:

  Constructs a new `boost::packaged_task` with `boost::forward<F>(f)` stored as the associated task.

Throws:

  Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data structures could not be allocated.

Notes:

  The R(*f)()) overload to allow passing a function without needing to use `&`.

###### Allocator Constructor

    template <class Allocator>
    packaged_task(allocator_arg_t, Allocator a, R(*f)());
    template <class F, class Allocator>
    packaged_task(allocator_arg_t, Allocator a, F&& f);

Preconditions:

  `f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same as invoking `f`.

Effects:

  Constructs a new `boost::packaged_task` with `boost::forward<F>(f)` stored as the associated task using the allocator `a`.

Throws:

  Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data structures could not be allocated.

Notes:

  Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.

Notes:

  The R(*f)()) overload to allow passing a function without needing to use `&`.

###### Move Constructor

    packaged_task(packaged_task && other);

Effects:

  Constructs a new `boost::packaged_task`, and transfers ownership of the task associated with `other` to `*this`, leaving `other` with no associated task.

Throws:

  Nothing.

Notes:

  If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

###### Move Assignment Operator

    packaged_task& operator=(packaged_task && other);

Effects:

  Transfers ownership of the task associated with `other` to `*this`, leaving `other` with no associated task. If there was already a task associated with `*this`, and that task has not been invoked, sets any futures associated with that task to ready with a `boost::broken_promise` exception as the result.

Throws:

  Nothing.

Notes:

  If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

###### Destructor

    ~packaged_task();

Effects:

  Destroys `*this`. If there was a task associated with `*this`, and that task has not been invoked, sets any futures associated with that task to ready with a `boost::broken_promise` exception as the result.

Throws:

  Nothing.

###### Member Function `get_future()`

     future<R> get_future();

Effects:

  Returns a `future` associated with the result of the task associated with `*this`.

Throws:

  `boost::task_moved` if ownership of the task associated with `*this` has been moved to another instance of `boost::packaged_task`. `boost::future_already_retrieved` if the future associated with the task has already been retrieved.

###### Member Function `operator()()`

    void operator()();

Effects:

  Invoke the task associated with `*this` and store the result in the corresponding future. If the task returns normally, the return value is stored as the asynchronous result, otherwise the exception thrown is stored. Any threads blocked waiting for the asynchronous result associated with this task are woken.

Postconditions:

  All futures waiting on the asynchronous result are ready

Throws:

  `boost::task_moved` if ownership of the task associated with `*this` has been moved to another instance of `boost::packaged_task`. `boost::task_already_started` if the task has already been invoked.

###### Member Function `reset()`

    void reset();

Effects:

  Reset the state of the packaged_task so that it can be called again.

Throws:

  `boost::task_moved` if ownership of the task associated with `*this` has been moved to another instance of `boost::packaged_task`.

###### Member Function `set_wait_callback()` EXTENSION

    template<typename F>
    void set_wait_callback(F f);

Preconditions:

  The expression `f(t)` where `t` is a lvalue of type `boost::packaged_task` shall be well-formed. Invoking a copy of `f` shall have the same effect as invoking `f`

Effects:

  Store a copy of `f` with the task associated with `*this` as a wait callback. This will replace any existing wait callback store alongside that task. If a thread subsequently calls one of the wait functions on a `future` or `boost::shared_future` associated with this task, and the result of the task is not ready, `f(*this)` shall be invoked.

Throws:

  `boost::task_moved` if ownership of the task associated with `*this` has been moved to another instance of `boost::packaged_task`.

##### Non-member function `decay_copy()`

    template <class T>
    typename decay<T>::type decay_copy(T&& v)
    {
      return boost::forward<T>(v);
    }

##### Non-member function `async()`

    template <class F>
     future<typename result_of<typename decay<F>::type()>::type>
    async(F f);
    template <class F>
     future<typename result_of<typename decay<F>::type()>::type>
    async(launch policy, F f);

The function template async provides a mechanism to launch a function potentially in a new thread and provides the result of the function in a future object with which it shares a shared state.

| Warning
`async(launch::deferred, F)` is NOT YET IMPLEMENTED!

Requires:

      decay_copy(boost::forward<F>(f))()

  shall be a valid expression.

Effects

  The first function behaves the same as a call to the second function with a policy argument of `launch::async | launch::deferred` and the same arguments for `F`. The second function creates a shared state that is associated with the returned future object.

  The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies):

  - if `policy & launch::async` is non-zero - calls `decay_copy(boost::forward<F>(f))()` as if in a new thread of execution represented by a thread object with the calls to `decay_copy()` being evaluated in the thread that called `async`. Any return value is stored as the result in the shared state. Any exception propagated from the execution of `decay_copy(boost::forward<F>(f))()` is stored as the exceptional result in the shared state. The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.

  - if `policy & launch::deferred` is non-zero - Stores `decay_copy(boost::forward<F>(f))` in the shared state. This copy of `f` constitute a deferred function. Invocation of the deferred function evaluates `boost::move(g)()` where `g` is the stored value of `decay_copy(boost::forward<F>(f))`. The shared state is not made ready until the function has completed. The first call to a non-timed waiting function on an asynchronous return object referring to this shared state shall invoke the deferred function in the thread that called the waiting function. Once evaluation of `boost::move(g)()` begins, the function is no longer considered deferred. (Note: If this policy is specified together with other policies, such as when using a policy value of `launch::async | launch::deferred`, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited.)

Returns:

  An object of type ``future`<typename result_of<typename decay<F>::type()>::type>` that refers to the shared state created by this call to `async`.

Synchronization:

  Regardless of the provided policy argument,

  - the invocation of `async` synchronizes with the invocation of `f`. (Note: This statement applies even when the corresponding future object is moved to another thread.); and

  - the completion of the function `f` is sequenced before the shared state is made ready. (Note: `f` might not be called at all, so its completion might never happen.)

  If the implementation chooses the `launch::async` policy,

  - a call to a waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined;

  - the associated thread completion synchronizes with the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first.

Throws:

  `system_error` if policy is `launch::async` and the implementation is unable to start a new thread.

Error conditions:

  - `resource_unavailable_try_again` - if policy is `launch::async` and the system is unable to start a new thread.

Remarks:

  The first signature shall not participate in overload resolution if decay<F>::type is boost::launch.

##### Non-member function `wait_for_any()`

    template<typename Iterator>
    Iterator wait_for_any(Iterator begin,Iterator end);

    template<typename F1,typename F2>
    unsigned wait_for_any(F1& f1,F2& f2);

    template<typename F1,typename F2,typename F3>
    unsigned wait_for_any(F1& f1,F2& f2,F3& f3);

    template<typename F1,typename F2,typename F3,typename F4>
    unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4);

    template<typename F1,typename F2,typename F3,typename F4,typename F5>
    unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5);

Preconditions:

  The types `Fn` shall be specializations of `future` or `boost::shared_future`, and `Iterator` shall be a forward iterator with a `value_type` which is a specialization of `future` or `boost::shared_future`.

Effects:

  Waits until at least one of the specified futures is ready.

Returns:

  The range-based overload returns an `Iterator` identifying the first future in the range that was detected as ready. The remaining overloads return the zero-based index of the first future that was detected as ready (first parameter => 0, second parameter => 1, etc.).

Throws:

  `boost::thread_interrupted` if the current thread is interrupted. Any exception thrown by the wait callback associated with any of the futures being waited for. `std::bad_alloc` if memory could not be allocated for the internal wait structures.

Notes:

  `wait_for_any()` is an interruption point.

##### Non-member function `wait_for_all()`

    template<typename Iterator>
    void wait_for_all(Iterator begin,Iterator end);

    template<typename F1,typename F2>
    void wait_for_all(F1& f1,F2& f2);

    template<typename F1,typename F2,typename F3>
    void wait_for_all(F1& f1,F2& f2,F3& f3);

    template<typename F1,typename F2,typename F3,typename F4>
    void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4);

    template<typename F1,typename F2,typename F3,typename F4,typename F5>
    void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5);

Preconditions:

  The types `Fn` shall be specializations of `future` or `boost::shared_future`, and `Iterator` shall be a forward iterator with a `value_type` which is a specialization of `future` or `boost::shared_future`.

Effects:

  Waits until all of the specified futures are ready.

Throws:

  Any exceptions thrown by a call to `wait()` on the specified futures.

Notes:

  `wait_for_all()` is an interruption point.