Added more member functions to the auto_mutex_readonly object that allows

you to convert between a readonly and write lock but still use RAII.
This commit is contained in:
Davis King 2014-06-23 15:20:16 -04:00
parent 964163c58d
commit 505cc7b1d9
3 changed files with 131 additions and 4 deletions

View File

@ -121,7 +121,25 @@ namespace
for (int i = 0; i < 6; ++i)
{
auto_mutex_readonly lock(m);
DLIB_TEST(lock.has_read_lock());
DLIB_TEST(!lock.has_write_lock());
do_readonly_stuff();
lock.lock_readonly();
DLIB_TEST(lock.has_read_lock());
DLIB_TEST(!lock.has_write_lock());
lock.unlock();
DLIB_TEST(!lock.has_read_lock());
DLIB_TEST(!lock.has_write_lock());
lock.lock_readonly();
DLIB_TEST(lock.has_read_lock());
DLIB_TEST(!lock.has_write_lock());
lock.lock_write();
DLIB_TEST(!lock.has_read_lock());
DLIB_TEST(lock.has_write_lock());
lock.lock_write();
DLIB_TEST(!lock.has_read_lock());
DLIB_TEST(lock.has_write_lock());
}
dlog << LINFO << "exit thread_readonly()";

View File

@ -107,7 +107,7 @@ namespace dlib
explicit auto_mutex_readonly (
const read_write_mutex& rw_
) : rw(rw_)
) : rw(rw_), _has_write_lock(false), _has_read_lock(true)
{
rw.lock_readonly();
}
@ -115,12 +115,57 @@ namespace dlib
~auto_mutex_readonly (
)
{
rw.unlock_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

View File

@ -81,8 +81,8 @@ namespace dlib
{
/*!
INITIAL VALUE
The mutex given in the constructor is locked and associated with this
object.
The mutex given in the constructor is locked using a read-only lock and
associated with this object.
WHAT THIS OBJECT REPRESENTS
This object represents a mechanism for automatically locking and unlocking
@ -97,6 +97,7 @@ namespace dlib
ensures
- #*this is properly initialized
- a readonly lock will be obtained on m using m.lock_readonly()
- #has_read_lock() == true
!*/
~auto_mutex_readonly (
@ -107,6 +108,69 @@ namespace dlib
- the mutex associated with *this has been unlocked
!*/
bool has_read_lock (
);
/*!
ensures
- returns true if this object has called read_write_mutex::lock_readonly()
on its associated mutex and has yet to release that lock.
!*/
bool has_write_lock (
);
/*!
ensures
- returns true if this object has called read_write_mutex::lock() on its
associated mutex and has yet to release that lock.
!*/
void lock_readonly (
);
/*!
ensures
- This function converts the lock on the associated mutex into a readonly lock.
Specifically:
if (!has_read_lock()) then
- if (has_write_lock()) then
- unlocks the associated mutex and then relocks it by calling
read_write_mutex::lock_readonly()
- else
- locks the associated mutex by calling read_write_mutex::lock_readonly()
- #has_read_lock() == true
- Note that the lock switch is not atomic. This means that whatever
resource is protected by the mutex might have been modified during the
call to lock_readonly().
!*/
void lock_write (
);
/*!
ensures
- This function converts the lock on the associated mutex into a write lock.
Specifically:
if (!has_write_lock()) then
- if (has_read_lock()) then
- unlocks the associated mutex and then relocks it by calling
read_write_mutex::lock()
- else
- locks the associated mutex by calling read_write_mutex::lock()
- #has_write_lock() == true
- Note that the lock switch is not atomic. This means that whatever
resource is protected by the mutex might have been modified during the
call to lock_write().
!*/
void unlock (
);
/*!
ensures
- if (has_read_lock() || has_write_lock()) then
- unlocks the associated mutex. This is useful if you want to unlock a
mutex before the auto_mutex_readonly destructor executes.
- #has_read_lock() == false
- #has_write_lock() == false
!*/
private:
// restricted functions
auto_mutex_readonly(auto_mutex_readonly&); // copy constructor