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