mirror of
https://github.com/davisking/dlib.git
synced 2024-11-01 10:14:53 +08:00
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:
parent
964163c58d
commit
505cc7b1d9
@ -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()";
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user