Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Other Lock Types - EXTENSION

Strict Locks
Class template strict_lock
Class template nested_strict_lock
Non Member Function make_strict_lock
Non Member Function make_nested_strict_lock
Locking pointers
Class template const_strict_lock_ptr
Class template strict_lock_ptr
Externally Locked
Template Class externally_locked
Template Class externally_locked<T&>
swap(externally_locked&, externally_locked&)
Class template shared_lock_guard
shared_lock_guard(SharedLockable & m)
shared_lock_guard(SharedLockable & m,boost::adopt_lock_t)
~shared_lock_guard()
Class template reverse_lock
reverse_lock(Lock & m)
~reverse_lock()
// #include <boost/thread/locks.hpp> 
// #include <boost/thread/strict_lock.hpp> 

namespace boost
{

  template<typename Lockable>
  class strict_lock;
  template <typename Lock>
  class nested_strict_lock;
  template <typename Lockable>
  struct is_strict_lock_sur_parole<strict_lock<Lockable> >;
  template <typename Lock>
  struct is_strict_lock_sur_parole<nested_strict_lock<Lock> >;

#if ! defined BOOST_THREAD_NO_MAKE_STRICT_LOCK
  template <typename Lockable>
  strict_lock<Lockable> make_strict_lock(Lockable& mtx);
#endif
#if ! defined BOOST_THREAD_NO_MAKE_NESTED_STRICT_LOCK
  template <typename Lock>
  nested_strict_lock<Lock> make_nested_strict_lock(Lock& lk);
#endif

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

template<typename BasicLockable>
class strict_lock
{
public:
    typedef BasicLockable mutex_type;
    strict_lock(strict_lock const& m_) = delete;
    strict_lock& operator=(strict_lock const& m_) = delete;
    explicit strict_lock(mutex_type& m_);
    ~strict_lock();

    bool owns_lock(mutex_type const* l) const noexcept;
};

strict_lock is a model of StrictLock.

strict_lock is the simplest StrictLock: on construction it acquires ownership of the implementation of the BasicLockable concept supplied as the constructor parameter. On destruction, the ownership is released. This provides simple RAII-style locking of a BasicLockable object, to facilitate exception-safe locking and unlocking.

See also boost::lock_guard

Effects:

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

Throws:

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

Effects:

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

Throws:

Nothing.

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

template<typename Lock>
class nested_strict_lock
{
public:
    typedef BasicLockable mutex_type;
    nested_strict_lock(nested_strict_lock const& m_) = delete;
    nested_strict_lock& operator=(nested_strict_lock const& m_) = delete;
    explicit nested_strict_lock(Lock& lk),
    ~nested_strict_lock() noexcept;

    bool owns_lock(mutex_type const* l) const noexcept;
};

nested_strict_lock is a model of StrictLock.

A nested strict lock is a scoped lock guard ensuring a mutex is locked on its scope, by taking ownership of a nesting lock, locking the mutex on construction if not already locked and restoring the ownership to the nesting lock on destruction.

See also strict_lock, boost::unique_lock

Requires:

lk.mutex() != null_ptr.

Effects:

Stores the reference to the lock parameter lk and takes ownership on it. If the lock doesn't owns the mutex lock it.

Postcondition:

owns_lock(lk.mutex()).

Throws:

- lock_error when BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and lk.mutex() == null_ptr

- Any exception that @c lk.lock() can throw.

Effects:

Restores ownership to the nesting lock.

Return:

Whether if this lock is locking that mutex.

template <typename Lockable>
strict_lock<Lockable> make_strict_lock(Lockable& m); // EXTENSION

Returns:

a strict_lock as if initialized with {m}.

Throws:

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

template <typename Lock>
nested_strict_lock<Lock> make_nested_strict_lock(Lock& lk); // EXTENSION

Returns:

a nested_strict_lock as if initialized with {lk}.

Throws:

Any exception thrown by the call to lk.lock().

// #include <boost/thread/synchroniezd_value.hpp> 
// #include <boost/thread/strict_lock_ptr.hpp> 

namespace boost
{

  template<typename T, typename Lockable = mutex>
  class strict_lock_ptr;
  template<typename T, typename Lockable = mutex>
  class const_strict_lock_ptr;
}
// #include <boost/thread/synchroniezd_value.hpp> 
// #include <boost/thread/strict_lock_ptr.hpp> 


template <typename T, typename Lockable = mutex>
class const_strict_lock_ptr
{
public:
  typedef T value_type;
  typedef Lockable mutex_type;

  const_strict_lock_ptr(const_strict_lock_ptr const& m_) = delete;
  const_strict_lock_ptr& operator=(const_strict_lock_ptr const& m_) = delete;

  const_strict_lock_ptr(T const& val, Lockable & mtx);
  const_strict_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t tag);

  ~const_strict_lock_ptr();

  const T* operator->() const;
  const T& operator*() const;

};
const_strict_lock_ptr(T const& val, Lockable & m);

Effects:

Invokes m.lock(), stores a reference to it and to the value type val.

Throws:

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

const_strict_lock_ptr(T const& val, Lockable & m, adopt_lock_t tag);

Effects:

Stores a reference to it and to the value type val.

Throws:

Nothing.

~const_strict_lock_ptr();

Effects:

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

Throws:

Nothing.

const T* operator->() const;

Return:

return a constant pointer to the protected value.

Throws:

Nothing.

const T& operator*() const;

Return:

return a constant reference to the protected value.

Throws:

Nothing.

// #include <boost/thread/synchroniezd_value.hpp> 
// #include <boost/thread/strict_lock_ptr.hpp> 

template <typename T, typename Lockable = mutex>
class strict_lock_ptr : public const_strict_lock_ptr<T,Lockable>
{
public:
  strict_lock_ptr(strict_lock_ptr const& m_) = delete;
  strict_lock_ptr& operator=(strict_lock_ptr const& m_) = delete;

  strict_lock_ptr(T & val, Lockable & mtx);
  strict_lock_ptr(T & val, Lockable & mtx, adopt_lock_t tag);
  ~strict_lock_ptr();

  T* operator->();
  T& operator*();

};
strict_lock_ptr(T const& val, Lockable & m);

Effects:

Invokes m.lock(), stores a reference to it and to the value type val.

Throws:

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

strict_lock_ptr(T const& val, Lockable & m, adopt_lock_t tag);

Effects:

Stores a reference to it and to the value type val.

Throws:

Nothing.

~ strict_lock_ptr();

Effects:

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

Throws:

Nothing.

T* operator->();

Return:

return a pointer to the protected value.

Throws:

Nothing.

T& operator*();

Return:

return a reference to the protected value.

Throws:

Nothing.

// #include <boost/thread/externally_locked.hpp>
template <class T, typename MutexType = boost::mutex>
class externally_locked;
template <class T, typename MutexType>
class externally_locked<T&, MutexType>;

template <typename T, typename MutexType>
void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs);
// #include <boost/thread/externally_locked.hpp>

template <class T, typename MutexType>
class externally_locked
{
  //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
  BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));

public:
  typedef MutexType mutex_type;

  externally_locked(mutex_type& mtx, const T& obj);
  externally_locked(mutex_type& mtx,T&& obj);
  explicit externally_locked(mutex_type& mtx);
  externally_locked(externally_locked const& rhs);
  externally_locked(externally_locked&& rhs);
  externally_locked& operator=(externally_locked const& rhs);
  externally_locked& operator=(externally_locked&& rhs);

  // observers
  T& get(strict_lock<mutex_type>& lk);
  const T& get(strict_lock<mutex_type>& lk) const;

  template <class Lock>
  T& get(nested_strict_lock<Lock>& lk);
  template <class Lock>
  const T& get(nested_strict_lock<Lock>& lk) const;

  template <class Lock>
  T& get(Lock& lk);
  template <class Lock>
  T const& get(Lock& lk) const;

 mutex_type* mutex() const noexcept;

  // modifiers
  void lock();
  void unlock();
  bool try_lock();
  void swap(externally_locked&);
};

externally_locked is a model of Lockable, it cloaks an object of type T, and actually provides full access to that object through the get and set member functions, provided you pass a reference to a strict lock object.

Only the specificities respect to Lockable are described here.

externally_locked(mutex_type& mtx, const T& obj);

Requires:

T is a model of CopyConstructible.

Effects:

Constructs an externally locked object copying the cloaked type.

Throws:

Any exception thrown by the call to T(obj).

externally_locked(mutex_type& mtx,T&& obj);

Requires:

T is a model of Movable.

Effects:

Constructs an externally locked object by moving the cloaked type.

Throws:

Any exception thrown by the call to T(obj).

externally_locked(mutex_type& mtx);

Requires:

T is a model of DefaultConstructible.

Effects:

Constructs an externally locked object by default constructing the cloaked type.

Throws:

Any exception thrown by the call to T().

externally_locked(externally_locked&& rhs);

Requires:

T is a model of Movable.

Effects:

Move constructs an externally locked object by moving the cloaked type and copying the mutex reference

Throws:

Any exception thrown by the call to T(T&&).

externally_locked(externally_locked& rhs);

Requires:

T is a model of Copyable.

Effects:

Copy constructs an externally locked object by copying the cloaked type and copying the mutex reference

Throws:

Any exception thrown by the call to T(T&).

externally_locked& operator=(externally_locked&& rhs);

Requires:

T is a model of Movable.

Effects:

Move assigns an externally locked object by moving the cloaked type and copying the mutex reference

Throws:

Any exception thrown by the call to T::operator=(T&&).

externally_locked& operator=(externally_locked const& rhs);

Requires:

T is a model of Copyable.

Effects:

Copy assigns an externally locked object by copying the cloaked type and copying the mutex reference

Throws:

Any exception thrown by the call to T::operator=(T&).

T& get(strict_lock<mutex_type>& lk);
const T& get(strict_lock<mutex_type>& lk) const;

Requires:

The lk parameter must be locking the associated mutex.

Returns:

A reference to the cloaked object

Throws:

lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and the run-time preconditions are not satisfied .

template <class Lock>
T& get(nested_strict_lock<Lock>& lk);
template <class Lock>
const T& get(nested_strict_lock<Lock>& lk) const;

Requires:

is_same<mutex_type, typename Lock::mutex_type> and the lk parameter must be locking the associated mutex.

Returns:

A reference to the cloaked object

Throws:

lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and the run-time preconditions are not satisfied .

template <class Lock>
T& get(Lock& lk);
template <class Lock>
T const& get(Lock& lk) const;

Requires:

Lock is a model of StrictLock, is_same<mutex_type, typename Lock::mutex_type> and the lk parameter must be locking the associated mutex.

Returns:

A reference to the cloaked object

Throws:

lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and the run-time preconditions are not satisfied .

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

template <class T, typename MutexType>
class externally_locked<T&, MutexType>
{
  //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
  BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));

public:
  typedef MutexType mutex_type;

  externally_locked(mutex_type& mtx, T& obj);
  explicit externally_locked(mutex_type& mtx);
  externally_locked(externally_locked const& rhs) noexcept;
  externally_locked(externally_locked&& rhs) noexcept;
  externally_locked& operator=(externally_locked const& rhs) noexcept;
  externally_locked& operator=(externally_locked&& rhs) noexcept;

  // observers
  T& get(strict_lock<mutex_type>& lk);
  const T& get(strict_lock<mutex_type>& lk) const;

  template <class Lock>
  T& get(nested_strict_lock<Lock>& lk);
  template <class Lock>
  const T& get(nested_strict_lock<Lock>& lk) const;

  template <class Lock>
  T& get(Lock& lk);
  template <class Lock>
  T const& get(Lock& lk) const;

 mutex_type* mutex() const noexcept;

  // modifiers
  void lock();
  void unlock();
  bool try_lock();
  void swap(externally_locked&) noexcept;
};

externally_locked is a model of Lockable, it cloaks an object of type T, and actually provides full access to that object through the get and set member functions, provided you pass a reference to a strict lock object.

Only the specificities respect to Lockable are described here.

externally_locked<T&>(mutex_type& mtx, T& obj) noexcept;

Effects:

Constructs an externally locked object copying the cloaked reference.

externally_locked(externally_locked&& rhs) noexcept;

Effects:

Moves an externally locked object by moving the cloaked type and copying the mutex reference

externally_locked& operator=(externally_locked&& rhs);

Effects:

Move assigns an externally locked object by copying the cloaked reference and copying the mutex reference

externally_locked& operator=(externally_locked const& rhs);

Requires:

T is a model of Copyable.

Effects:

Copy assigns an externally locked object by copying the cloaked reference and copying the mutex reference

Throws:

Any exception thrown by the call to T::operator=(T&).

T& get(strict_lock<mutex_type>& lk);
const T& get(strict_lock<mutex_type>& lk) const;

Requires:

The lk parameter must be locking the associated mutex.

Returns:

A reference to the cloaked object

Throws:

lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and the run-time preconditions are not satisfied .

template <class Lock>
T& get(nested_strict_lock<Lock>& lk);
template <class Lock>
const T& get(nested_strict_lock<Lock>& lk) const;

Requires:

is_same<mutex_type, typename Lock::mutex_type> and the lk parameter must be locking the associated mutex.

Returns:

A reference to the cloaked object

Throws:

lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and the run-time preconditions are not satisfied .

template <class Lock>
T& get(Lock& lk);
template <class Lock>
T const& get(Lock& lk) const;

Requires:

Lock is a model of StrictLock, is_same<mutex_type, typename Lock::mutex_type> and the lk parameter must be locking the associated mutex.

Returns:

A reference to the cloaked object

Throws:

lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and the run-time preconditions are not satisfied .

template <typename T, typename MutexType>
void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs)
// #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.

Effects:

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

Throws:

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

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.

Effects:

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

Throws:

Nothing.

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

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

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:

Any exception thrown by mtx->lock().

Remarks:

Note that if mtx->lock() throws an exception while unwinding the program will terminate, so don't use reverse_lock if an exception can be thrown.


PrevUpHomeNext