Class template monitor_ptr
poet::monitor_ptr — A smart pointer which provides automatically locked access to an object.
Synopsis
template<typename T, typename Mutex = boost::mutex> class monitor_ptr { public: // types typedef T element_type; typedef Mutex mutex_type; // construct/copy/destruct monitor_ptr(); template<typename U> explicit monitor_ptr(U*); monitor_ptr(boost::shared_ptr<T>); monitor_ptr(const monitor_ptr &); template<typename U> monitor_ptr(const monitor_ptr<U, Mutex> &); template<typename U> monitor_ptr(const monitor_ptr<U, Mutex> &, T*); monitor_ptr& operator=(const monitor_ptr &); virtual ~monitor_ptr(); // public member functions const boost::shared_ptr<T> & direct() const; monitor_unique_lock<const monitor_ptr> operator->() const; operator bool() const; template<typename U> void reset(U*); void reset(const boost::shared_ptr<T> &); void reset(); template<typename U> void reset(const monitor_ptr<U, Mutex> &, T*); void swap(monitor_ptr &); // Boost.Thread Lockable concept support void lock() const; bool try_lock() const; void unlock() const; // Boost.Thread TimedLockable concept support template<typename Timeout> bool timed_lock(const Timeout &) const; // Boost.Thread SharedLockable concept support void lock_shared() const; bool try_lock_shared() const; template<typename Timeout> bool timed_lock_shared(const Timeout &) const; void unlock_shared() const; void unlock_and_lock_shared() const; // Boost.Thread UpgradeLockable concept support void lock_upgrade() const; void unlock_upgrade() const; void unlock_upgrade_and_lock() const; void unlock_upgrade_and_lock_shared() const; void unlock_and_lock_upgrade() const; }; // free functions: casts template<typename T, typename U, typename Mutex> monitor_ptr<T, Mutex> static_pointer_cast(const monitor_ptr<U, Mutex> &); template<typename T, typename U, typename Mutex> monitor_ptr<T, Mutex> dynamic_pointer_cast(const monitor_ptr<U, Mutex> &); template<typename T, typename U, typename Mutex> monitor_ptr<T, Mutex> const_pointer_cast(const monitor_ptr<U, Mutex> &); // free functions: comparison template<typename T, typename MutexA, typename U, typename MutexB> bool operator==(const monitor_ptr<T, MutexT> &, const monitor_ptr<U, MutexU> &); template<typename T, typename MutexA, typename U, typename MutexB> bool operator!=(const monitor_ptr<T, MutexT> &, const monitor_ptr<U, MutexU> &); template<typename T, typename MutexA, typename U, typename MutexB> bool operator<(const monitor_ptr<T, MutexT> &, const monitor_ptr<U, MutexU> &); // free function: swap template<typename T, typename Mutex> void swap(monitor_ptr<T, Mutex> &, monitor_ptr<T, Mutex> &);
Description
monitor_ptr
allows for the easy creation of monitor objects. A
monitor_ptr
provides automatically locked access to an object's members
when they are accessed through the overloaded operator->,
or alternatively through one of the lock classes from
poet/monitor_locks.hpp.
It is based in part on ideas taken from
"Wrapping C++ Member Function Calls"
by Bjarne Stroustroup and "Monitor Object:
An Object Behavioral Pattern for Concurrent Programming" by Douglas C. Schmidt.
Although any object may be passed to a monitor_ptr
, special support is provided
for classes derived from monitor_base. This allows classes derived from
monitor_base to wait on conditions inside member function calls,
releasing the monitor_ptr
's mutex until the condition is met.
The Mutex
template type parameter must model the Lockable
concept from the Boost.Thread library. The monitor_ptr
itself models the
Lockable
concept, and will also model any of the
TimedLockable
, SharedLockable
, or UpgradeLockable
concepts if the underlying Mutex
template type supports them.
Note however, a monitor_ptr
must not be empty when being used as
a mutex. An empty monitor_ptr
will throw a
boost::lock_error if any attempt is made to use
lock, unlock, or any other
part of the monitor_ptr
interface which models the Boost.Thread concepts.
The interfaces defined by the Boost.Thread mutex concepts should generally not be used directly by the user. They are intended to be used by scoped lock classes such as monitor_unique_lock, which provide a safer means to perform locking. See the "Mutex Concepts" documentation in the Boost.Thread library for more information about the Lockable, etc. concepts.
Note that while monitor_ptr
provides thread-safe access to the object
it is pointing at, it does not provide a strong thread-safety guarantee
for itself.
That is, a single
monitor_ptr
object should not be modified concurrently by multiple
threads. Rather, each thread should be passed its own copy of the
monitor_ptr
to use. The thread-safety guarantees of
monitor_ptr
are similar to those provided by boost::shared_ptr.
Example Code
See also
-
monitor: an alternative to the
monitor_ptr
class, which stores its wrapped object by value instead of acting like a pointer.
monitor_ptr
public construct/copy/destruct
-
monitor_ptr();
The default constructor creates an empty
monitor_ptr
. -
template<typename U> explicit monitor_ptr(U* pointer);
Creates a
monitor_ptr
which wraps the specified pointer. Themonitor_ptr
internally storespointer
in aboost::shared_ptr
. Thus the pointer will be automatically deleted when the last copy of thismonitor_ptr
is destroyed. -
monitor_ptr(boost::shared_ptr<T> smart_pointer);
Creates a
monitor_ptr
which wraps the specified pointer. This constructor allows themonitor_ptr
to be initialized with aboost::shared_ptr
that has a custom deleter. -
monitor_ptr(const monitor_ptr & other);
The copy constructor creates a
monitor_ptr
which shares the same pointer, mutex, and condition as the original. -
template<typename U> monitor_ptr(const monitor_ptr<U, Mutex> & other);
This constructor creates a
monitor_ptr
which shares the same pointer (implicitly converted), mutex, and condition as the original. -
template<typename U> monitor_ptr(const monitor_ptr<U, Mutex> & other, T* pointer);
This is an aliasing constructor, similar in function to the aliasing constructor of
shared_ptr
. It creates amonitor_ptr
which shares ownership and uses the same mutex asother
, but which points at the object specified bypointer
when dereferenced. The typesT
andU
may be unrelated. It is useful for creatingmonitor_ptr
s to objects which are only indirectly owned by amonitor_ptr
, for example:struct coordinates { int x; int y; }; // ... poet::monitor_ptr<coordinates> coords(new coordinates()); // x_mon shares ownership of coords object, but points at coords->x. // x_mon might be needed to pass the x member of the coords object to a function // expecting an argument of type poet::monitor_ptr<int>. poet::monitor_ptr<int> x_mon(coords, &coords->x); // the following block has the same effect as "coords->x = 5;" { poet::monitor_unique_lock<monitor_ptr<int> > x_lock(x_mon); *x_lock = 5; }
-
monitor_ptr& operator=(const monitor_ptr & rhs);
After assignment, the two
monitor_ptr
s will share the same pointer, mutex, and condition variable. -
virtual ~monitor_ptr();
A
monitor_ptr
and all its copies share ownership of an underlying pointer, mutex, and condition variable. The pointer, mutex, and condition are deleted when the last copy of themonitor_ptr
is destroyed. The deleter for the underlying pointer may be customized by using the constructor which takes aboost::shared_ptr
as its parameter.
monitor_ptr
public member functions
-
const boost::shared_ptr<T> & direct() const;
Gives direct unlocked access to the underlying pointer.
-
monitor_unique_lock<const monitor_ptr> operator->() const;
Returns a temporary
monitor_unique_lock
which locks themonitor_ptr
's mutex. Theoperator->()
of the returnedmonitor_unique_lock
object will be automatically called in turn (overloadingoperator->()
is special in that way), which will utimately result in a call ofoperator->()
on themonitor_ptr
's underlying pointer. The mutex is automatically unlocked after the member access completes by themonitor_unique_lock
destructor.If more flexibility is desired, the lock types from poet/monitor_locks.hpp provide alternatives to
monitor_ptr::operator->
. -
operator bool() const;
Conversion to
bool
results infalse
if themonitor_ptr
's underlying pointer is null,true
otherwise. -
template<typename U> void reset(U* pointer); void reset(const boost::shared_ptr<T> & smart_pointer); void reset(); template<typename U> void reset(const monitor_ptr<U, Mutex> & other, T* pointer);
Resets the
monitor_ptr
's underlying pointer using the specified parameter(s). A new mutex and condition are also created (except in the no-parameter case, where they are simply deleted).The overload which takes a
monitor_ptr
andT*
argument makes*this
into an aliasedmonitor_ptr
, which shares ownership and its mutex withother
, but which points at the address given bypointer
. See the description of the aliasing constructor for more information. -
void swap(monitor_ptr & other);
Swaps
*this
andother
.
monitor_ptr
free functions: casts
-
template<typename T, typename U, typename Mutex> monitor_ptr<T, Mutex> static_pointer_cast(const monitor_ptr<U, Mutex> & p);
Casts a
monitor_ptr
by applyingboost::static_pointer_cast<U>
to themonitor_ptr
's underlyingshared_ptr
. -
template<typename T, typename U, typename Mutex> monitor_ptr<T, Mutex> dynamic_pointer_cast(const monitor_ptr<U, Mutex> & p);
Casts a
monitor_ptr
by applyingboost::dynamic_pointer_cast<U>
to themonitor_ptr
's underlyingshared_ptr
. -
template<typename T, typename U, typename Mutex> monitor_ptr<T, Mutex> const_pointer_cast(const monitor_ptr<U, Mutex> & p);
Casts a
monitor_ptr
by applyingboost::const_pointer_cast<U>
to themonitor_ptr
's underlyingshared_ptr
.
monitor_ptr
free functions: comparison
-
template<typename T, typename MutexA, typename U, typename MutexB> bool operator==(const monitor_ptr<T, MutexT> & a, const monitor_ptr<U, MutexU> & b);
Returns:
Returns the result of applying
operator==
to the underlyingshared_ptr
s of the twomonitor_ptr
arguments. -
template<typename T, typename MutexA, typename U, typename MutexB> bool operator!=(const monitor_ptr<T, MutexT> & a, const monitor_ptr<U, MutexU> & b);
Returns:
Returns the result of applying
operator!=
to the underlyingshared_ptr
s of the twomonitor_ptr
arguments. -
template<typename T, typename MutexA, typename U, typename MutexB> bool operator<(const monitor_ptr<T, MutexT> & a, const monitor_ptr<U, MutexU> & b);
Returns:
Returns the result of applying
operator<
to the underlyingshared_ptr
s of the twomonitor_ptr
arguments.