mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[util] Add release() and reaquire() to scoped_lock
Added methods for releasing the lock held in a scoped_lock early, as well as reacquiring it after. Useful when, eg a thread is about to block and should not be holding the lock while blocked.
This commit is contained in:
@@ -34,18 +34,37 @@ class scoped_lock
|
|||||||
public:
|
public:
|
||||||
inline scoped_lock(
|
inline scoped_lock(
|
||||||
spinlock &lock,
|
spinlock &lock,
|
||||||
const char *where = __builtin_FUNCTION()
|
const char *where = __builtin_FUNCTION()) :
|
||||||
) : m_lock(lock), m_waiter {false, nullptr, where} {
|
m_lock(lock),
|
||||||
|
m_waiter {false, nullptr, where},
|
||||||
|
m_is_locked {false}
|
||||||
|
{
|
||||||
m_lock.acquire(&m_waiter);
|
m_lock.acquire(&m_waiter);
|
||||||
|
m_is_locked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ~scoped_lock() {
|
inline ~scoped_lock() { release(); }
|
||||||
m_lock.release(&m_waiter);
|
|
||||||
|
/// Re-acquire the previously-held lock
|
||||||
|
inline void reacquire() {
|
||||||
|
if (!m_is_locked) {
|
||||||
|
m_lock.acquire(&m_waiter);
|
||||||
|
m_is_locked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Release the held lock
|
||||||
|
inline void release() {
|
||||||
|
if (m_is_locked) {
|
||||||
|
m_lock.release(&m_waiter);
|
||||||
|
m_is_locked = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
spinlock &m_lock;
|
spinlock &m_lock;
|
||||||
spinlock::waiter m_waiter;
|
spinlock::waiter m_waiter;
|
||||||
|
bool m_is_locked;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Scoped lock that owns a spinlock::waiter and calls
|
/// Scoped lock that owns a spinlock::waiter and calls
|
||||||
@@ -57,18 +76,18 @@ public:
|
|||||||
spinlock &lock,
|
spinlock &lock,
|
||||||
const char *where = __builtin_FUNCTION()
|
const char *where = __builtin_FUNCTION()
|
||||||
) : m_lock(lock), m_waiter {false, nullptr, where} {
|
) : m_lock(lock), m_waiter {false, nullptr, where} {
|
||||||
m_locked = m_lock.try_acquire(&m_waiter);
|
m_is_locked = m_lock.try_acquire(&m_waiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ~scoped_trylock() {
|
inline ~scoped_trylock() {
|
||||||
if (m_locked)
|
if (m_is_locked)
|
||||||
m_lock.release(&m_waiter);
|
m_lock.release(&m_waiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool locked() const { return m_locked; }
|
inline bool locked() const { return m_is_locked; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_locked;
|
bool m_is_locked;
|
||||||
spinlock &m_lock;
|
spinlock &m_lock;
|
||||||
spinlock::waiter m_waiter;
|
spinlock::waiter m_waiter;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user