// Copyright (C) 2005 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_AUTO_MUTEX_EXTENSIOn_ #define DLIB_AUTO_MUTEX_EXTENSIOn_ #include "threads_kernel.h" #include "rmutex_extension.h" #include "read_write_mutex_extension.h" #include "auto_mutex_extension_abstract.h" namespace dlib { // ---------------------------------------------------------------------------------------- class auto_mutex { /*! INITIAL VALUE - if (m != 0) then - the mutex pointed to by m is locked - if (r != 0) then - the mutex pointed to by r is locked - if (rw != 0) then - the mutex pointed to by rw is locked - exactly one of r, m, or rw is not 0. CONVENTION - if (m != 0) then - the mutex pointed to by m is locked - if (r != 0) then - the mutex pointed to by r is locked - if (rw != 0) then - the mutex pointed to by rw is locked - exactly one of r, m, or rw is not 0. !*/ public: explicit auto_mutex ( const mutex& m_ ) : m(&m_), r(0), rw(0) { m->lock(); } explicit auto_mutex ( const rmutex& r_ ) : m(0), r(&r_), rw(0) { r->lock(); } explicit auto_mutex ( const read_write_mutex& rw_ ) : m(0), r(0), rw(&rw_) { rw->lock(); } void unlock() { if (m != 0) { m->unlock(); m = 0; } else if (r != 0) { r->unlock(); r = 0; } else if (rw != 0) { rw->unlock(); rw = 0; } } ~auto_mutex ( ) { unlock(); } private: const mutex* m; const rmutex* r; const read_write_mutex* rw; // restricted functions auto_mutex(auto_mutex&); // copy constructor auto_mutex& operator=(auto_mutex&); // assignment operator }; // ---------------------------------------------------------------------------------------- class auto_mutex_readonly { public: explicit auto_mutex_readonly ( const read_write_mutex& rw_ ) : rw(rw_), _has_write_lock(false), _has_read_lock(true) { rw.lock_readonly(); } ~auto_mutex_readonly ( ) { unlock(); } void lock_readonly ( ) { if (!_has_read_lock) { unlock(); rw.lock_readonly(); _has_read_lock = true; } } void lock_write ( ) { if (!_has_write_lock) { unlock(); rw.lock(); _has_write_lock = true; } } void unlock ( ) { if (_has_write_lock) { rw.unlock(); _has_write_lock = false; } else if (_has_read_lock) { rw.unlock_readonly(); _has_read_lock = false; } } bool has_read_lock ( ) { return _has_read_lock; } bool has_write_lock ( ) { return _has_write_lock; } private: const read_write_mutex& rw; bool _has_write_lock; bool _has_read_lock; // restricted functions auto_mutex_readonly(auto_mutex_readonly&); // copy constructor auto_mutex_readonly& operator=(auto_mutex_readonly&); // assignment operator }; // ---------------------------------------------------------------------------------------- } #endif // DLIB_AUTO_MUTEX_EXTENSIOn_