mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:37:45 +00:00
Kernel: Allow MutexLocker to be conditionally initialized
There are cases where we want to conditionally take a lock, but still would like to use an RAII type to make sure we don't leak the lock. This was previously impossible to do with `MutexLocker` due to it's design. This commit tweaks the design to allow the object to be initialized to an "empty" state without a lock associated, so it does nothing, and then later a lock can be "attached" to the locker. I realized that the get_lock() API's where also unused, and would no longer make sense for empty locks, so they were removed.
This commit is contained in:
parent
354e18a5a0
commit
bb1fa019de
1 changed files with 35 additions and 10 deletions
|
@ -106,18 +106,26 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class MutexLocker {
|
class MutexLocker {
|
||||||
|
AK_MAKE_NONCOPYABLE(MutexLocker);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
ALWAYS_INLINE explicit MutexLocker()
|
||||||
|
: m_lock(nullptr)
|
||||||
|
, m_locked(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#if LOCK_DEBUG
|
#if LOCK_DEBUG
|
||||||
ALWAYS_INLINE explicit MutexLocker(Mutex& l, Mutex::Mode mode = Mutex::Mode::Exclusive, const SourceLocation& location = SourceLocation::current())
|
ALWAYS_INLINE explicit MutexLocker(Mutex& l, Mutex::Mode mode = Mutex::Mode::Exclusive, const SourceLocation& location = SourceLocation::current())
|
||||||
#else
|
#else
|
||||||
ALWAYS_INLINE explicit MutexLocker(Mutex& l, Mutex::Mode mode = Mutex::Mode::Exclusive)
|
ALWAYS_INLINE explicit MutexLocker(Mutex& l, Mutex::Mode mode = Mutex::Mode::Exclusive)
|
||||||
#endif
|
#endif
|
||||||
: m_lock(l)
|
: m_lock(&l)
|
||||||
{
|
{
|
||||||
#if LOCK_DEBUG
|
#if LOCK_DEBUG
|
||||||
m_lock.lock(mode, location);
|
m_lock->lock(mode, location);
|
||||||
#else
|
#else
|
||||||
m_lock.lock(mode);
|
m_lock->lock(mode);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,11 +134,30 @@ public:
|
||||||
if (m_locked)
|
if (m_locked)
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void unlock()
|
ALWAYS_INLINE void unlock()
|
||||||
{
|
{
|
||||||
|
VERIFY(m_lock);
|
||||||
VERIFY(m_locked);
|
VERIFY(m_locked);
|
||||||
m_locked = false;
|
m_locked = false;
|
||||||
m_lock.unlock();
|
m_lock->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LOCK_DEBUG
|
||||||
|
ALWAYS_INLINE void attach_and_lock(Mutex& lock, Mutex::Mode mode = Mutex::Mode::Exclusive, const SourceLocation& location = SourceLocation::current())
|
||||||
|
#else
|
||||||
|
ALWAYS_INLINE void attach_and_lock(Mutex& lock, Mutex::Mode mode = Mutex::Mode::Exclusive)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
VERIFY(!m_locked);
|
||||||
|
m_lock = &lock;
|
||||||
|
m_locked = true;
|
||||||
|
|
||||||
|
#if LOCK_DEBUG
|
||||||
|
m_lock->lock(mode, location);
|
||||||
|
#else
|
||||||
|
m_lock->lock(mode);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LOCK_DEBUG
|
#if LOCK_DEBUG
|
||||||
|
@ -139,21 +166,19 @@ public:
|
||||||
ALWAYS_INLINE void lock(Mutex::Mode mode = Mutex::Mode::Exclusive)
|
ALWAYS_INLINE void lock(Mutex::Mode mode = Mutex::Mode::Exclusive)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
VERIFY(m_lock);
|
||||||
VERIFY(!m_locked);
|
VERIFY(!m_locked);
|
||||||
m_locked = true;
|
m_locked = true;
|
||||||
|
|
||||||
#if LOCK_DEBUG
|
#if LOCK_DEBUG
|
||||||
m_lock.lock(mode, location);
|
m_lock->lock(mode, location);
|
||||||
#else
|
#else
|
||||||
m_lock.lock(mode);
|
m_lock->lock(mode);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex& get_lock() { return m_lock; }
|
|
||||||
const Mutex& get_lock() const { return m_lock; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex& m_lock;
|
Mutex* m_lock;
|
||||||
bool m_locked { true };
|
bool m_locked { true };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue