Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Lock Types

Class template unique_lock
unique_lock()
unique_lock(Lockable & m)
unique_lock(Lockable & m,boost::adopt_lock_t)
unique_lock(Lockable & m,boost::defer_lock_t)
unique_lock(Lockable & m,boost::try_to_lock_t)
unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)
unique_lock(shared_lock<mutex_type>&&, const chrono::time_point<Clock, Duration>&)
unique_lock(shared_lock<mutex_type>&&, const chrono::duration<Rep, Period>&)
unique_lock(Lockable & m,boost::system_time const& abs_time)
template <class Clock, class Duration> unique_lock(Lockable & m,const chrono::time_point<Clock, Duration>& abs_time)
template <class Rep, class Period> unique_lock(Lockable & m,const chrono::duration<Rep, Period>& abs_time)
~unique_lock()
bool owns_lock() const
Lockable* mutex() const noexcept
explicit operator bool() const
Lockable* release()
Class template shared_lock - C++14
shared_lock()
shared_lock(Lockable & m)
shared_lock(Lockable & m,boost::adopt_lock_t)
shared_lock(Lockable & m,boost::defer_lock_t)
shared_lock(Lockable & m,boost::try_to_lock_t)
shared_lock(Lockable & m,boost::system_time const& abs_time)
~shared_lock()
bool owns_lock() const
Lockable* mutex() const
explicit operator bool() const
Lockable* release()
Class template upgrade_lock - EXTENSION
Class template upgrade_to_unique_lock -- EXTENSION
Mutex-specific class scoped_try_lock -- DEPRECATED
// #include <boost/thread/locks.hpp> 
// #include <boost/thread/lock_types.hpp> 

namespace boost
{

  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; // C++14
  template<typename Mutex>
  void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs); // C++14
  template<typename Lockable>
  class upgrade_lock; // EXTENSION
  template<typename Mutex>
  void swap(upgrade_lock <Mutex>& lhs, upgrade_lock <Mutex>& rhs); // EXTENSION
  template <class Mutex>
  class upgrade_to_unique_lock; // EXTENSION
}
// #include <boost/thread/locks.hpp>
// #include <boost/thread/lock_types.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); // C++14 
    template <class Clock, class Duration>
    unique_lock(shared_lock<mutex_type>&& sl,
                const chrono::time_point<Clock, Duration>& abs_time); // C++14
    template <class Rep, class Period>
    unique_lock(shared_lock<mutex_type>&& sl,
                const chrono::duration<Rep, Period>& rel_time); // C++14
#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; // EXTENSION

    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;

    mutex_type* mutex() const noexcept;

#if defined BOOST_THREAD_USE_DATE_TIME || 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.

Effects:

Creates a lock object with no associated mutex.

Postcondition:

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

Throws:

Nothing.

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

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.

Effects:

Stores a reference to m.

Postcondition:

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

Throws:

Nothing.

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.

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

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

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

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

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

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

Effects:

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

Throws:

Nothing.

Returns:

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

Throws:

Nothing.

Returns:

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

Throws:

Nothing.

Returns:

owns_lock()().

Throws:

Nothing.

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.

// #include <boost/thread/locks.hpp>
// #include <boost/thread/lock_types.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); // EXTENSION

    // 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_USE_DATE_TIME || 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.

Effects:

Creates a lock object with no associated mutex.

Postcondition:

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

Throws:

Nothing.

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

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.

Effects:

Stores a reference to m.

Postcondition:

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

Throws:

Nothing.

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.

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

Effects:

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

Throws:

Nothing.

Returns:

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

Throws:

Nothing.

Returns:

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

Throws:

Nothing.

Returns:

owns_lock().

Throws:

Nothing.

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.

// #include <boost/thread/locks.hpp>
// #include <boost/thread/lock_types.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.

// #include <boost/thread/locks.hpp>
// #include <boost/thread/lock_types.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;
    mutex_type* mutex() 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.

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


PrevUpHomeNext