Added the last useful features I dare imagine: A Lock() method and the

possibility to initialize the AutoLocker without locking the object even
if it is unlocked yet. Especially in loops Lock()/Unlock() come handy
when an otherwise constantly hold lock needs to be unlocked for a short
time.

I suppose we should move the kernel utils AutoLocker implementation
to headers/private/shared, and drop the less powerful ObjectLocker.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20405 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-03-23 00:03:59 +00:00
parent 8260e407c5
commit 27810ccf5e
2 changed files with 74 additions and 57 deletions

View File

@ -69,49 +69,64 @@ public:
{
}
inline AutoLocker(Lockable *lockable, bool alreadyLocked = false)
inline AutoLocker(Lockable *lockable, bool alreadyLocked = false,
bool lockIfNotLocked = true)
: fLockable(lockable),
fLocked(fLockable && alreadyLocked)
{
if (!fLocked)
_Lock();
if (!alreadyLocked && lockIfNotLocked)
Lock();
}
inline AutoLocker(Lockable &lockable, bool alreadyLocked = false)
inline AutoLocker(Lockable &lockable, bool alreadyLocked = false,
bool lockIfNotLocked = true)
: fLockable(&lockable),
fLocked(fLockable && alreadyLocked)
{
if (!fLocked)
_Lock();
if (!alreadyLocked && lockIfNotLocked)
Lock();
}
inline ~AutoLocker()
{
_Unlock();
Unlock();
}
inline void SetTo(Lockable *lockable, bool alreadyLocked)
inline void SetTo(Lockable *lockable, bool alreadyLocked,
bool lockIfNotLocked = true)
{
_Unlock();
Unlock();
fLockable = lockable;
fLocked = alreadyLocked;
if (!fLocked)
_Lock();
if (!alreadyLocked && lockIfNotLocked)
Lock();
}
inline void SetTo(Lockable &lockable, bool alreadyLocked)
inline void SetTo(Lockable &lockable, bool alreadyLocked,
bool lockIfNotLocked = true)
{
SetTo(&lockable, alreadyLocked);
SetTo(&lockable, alreadyLocked, lockIfNotLocked);
}
inline void Unset()
{
_Unlock();
Unlock();
Detach();
}
inline bool Lock()
{
if (fLockable && !fLocked)
fLocked = fLocking.Lock(fLockable);
return fLocked;
}
inline void Unlock()
{
_Unlock();
if (fLockable && fLocked) {
fLocking.Unlock(fLockable);
fLocked = false;
}
}
inline void Detach()
@ -136,21 +151,6 @@ public:
inline operator bool() const { return fLocked; }
private:
inline void _Lock()
{
if (fLockable)
fLocked = fLocking.Lock(fLockable);
}
inline void _Unlock()
{
if (fLockable && fLocked) {
fLocking.Unlock(fLockable);
fLocked = false;
}
}
private:
Lockable *fLockable;
bool fLocked;

View File

@ -77,27 +77,35 @@ public:
}
};
// AutoLocker
template<typename Lockable,
typename Locking = AutoLockerStandardLocking<Lockable> >
class AutoLocker {
private:
typedef AutoLocker<Lockable, Locking> ThisClass;
public:
inline AutoLocker(Lockable *lockable, bool alreadyLocked = false)
inline AutoLocker()
: fLockable(NULL),
fLocked(false)
{
}
inline AutoLocker(Lockable *lockable, bool alreadyLocked = false,
bool lockIfNotLocked = true)
: fLockable(lockable),
fLocked(fLockable && alreadyLocked)
{
if (!fLocked)
_Lock();
if (!alreadyLocked && lockIfNotLocked)
Lock();
}
inline AutoLocker(Lockable &lockable, bool alreadyLocked = false)
inline AutoLocker(Lockable &lockable, bool alreadyLocked = false,
bool lockIfNotLocked = true)
: fLockable(&lockable),
fLocked(fLockable && alreadyLocked)
{
if (!fLocked)
_Lock();
if (!alreadyLocked && lockIfNotLocked)
Lock();
}
inline ~AutoLocker()
@ -105,23 +113,47 @@ public:
Unlock();
}
inline void SetTo(Lockable *lockable, bool alreadyLocked)
inline void SetTo(Lockable *lockable, bool alreadyLocked,
bool lockIfNotLocked = true)
{
Unlock();
fLockable = lockable;
fLocked = alreadyLocked;
if (!fLocked)
_Lock();
if (!alreadyLocked && lockIfNotLocked)
Lock();
}
inline void SetTo(Lockable &lockable, bool alreadyLocked)
inline void SetTo(Lockable &lockable, bool alreadyLocked,
bool lockIfNotLocked = true)
{
SetTo(&lockable, alreadyLocked);
SetTo(&lockable, alreadyLocked, lockIfNotLocked);
}
inline void Unset()
{
Unlock();
Detach();
}
inline bool Lock()
{
if (fLockable && !fLocked)
fLocked = fLocking.Lock(fLockable);
return fLocked;
}
inline void Unlock()
{
if (fLockable && fLocked) {
fLocking.Unlock(fLockable);
fLocked = false;
}
}
inline void Detach()
{
fLockable = NULL;
fLocked = false;
}
inline AutoLocker<Lockable, Locking> &operator=(Lockable *lockable)
@ -138,23 +170,8 @@ public:
inline bool IsLocked() const { return fLocked; }
inline void Unlock()
{
if (fLockable && fLocked) {
fLocking.Unlock(fLockable);
fLocked = false;
}
}
inline operator bool() const { return fLocked; }
private:
inline void _Lock()
{
if (fLockable)
fLocked = fLocking.Lock(fLockable);
}
private:
Lockable *fLockable;
bool fLocked;