2019-06-16 21:10:38 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
class AeLocker
|
|
|
|
{
|
|
|
|
bool m_fArmed = false;
|
|
|
|
|
|
|
|
public:
|
|
|
|
AeLocker()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-10-23 20:21:49 +00:00
|
|
|
void arm(client *c = nullptr, bool fIfNeeded = false) // if a client is passed, then the client is already locked
|
2019-06-16 21:10:38 -04:00
|
|
|
{
|
2020-01-11 19:28:13 -05:00
|
|
|
if (m_fArmed)
|
|
|
|
return;
|
|
|
|
|
2020-07-10 11:33:47 +03:00
|
|
|
if (fIfNeeded && aeThreadOwnsLock())
|
|
|
|
return;
|
|
|
|
|
2020-01-27 19:59:04 -05:00
|
|
|
serverAssertDebug(!GlobalLocksAcquired());
|
|
|
|
|
2019-06-16 21:10:38 -04:00
|
|
|
if (c != nullptr)
|
|
|
|
{
|
|
|
|
serverAssert(c->lock.fOwnLock());
|
|
|
|
|
2019-06-17 21:53:04 -04:00
|
|
|
if (!aeTryAcquireLock(true /*fWeak*/)) // avoid locking the client if we can
|
2019-06-16 21:10:38 -04:00
|
|
|
{
|
2019-06-17 21:53:04 -04:00
|
|
|
bool fOwnClientLock = true;
|
2019-07-12 20:46:50 -04:00
|
|
|
int clientNesting = 1;
|
2019-06-17 21:53:04 -04:00
|
|
|
for (;;)
|
2019-06-16 21:10:38 -04:00
|
|
|
{
|
2019-06-17 21:53:04 -04:00
|
|
|
if (fOwnClientLock)
|
|
|
|
{
|
2019-07-12 20:46:50 -04:00
|
|
|
clientNesting = c->lock.unlock_recursive();
|
2019-06-17 21:53:04 -04:00
|
|
|
fOwnClientLock = false;
|
|
|
|
}
|
|
|
|
aeAcquireLock();
|
|
|
|
if (!c->lock.try_lock(false)) // ensure a strong try because aeAcquireLock is expensive
|
|
|
|
{
|
|
|
|
aeReleaseLock();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2019-06-16 21:10:38 -04:00
|
|
|
}
|
2019-07-12 20:46:50 -04:00
|
|
|
c->lock.lock_recursive(clientNesting);
|
2019-06-16 21:10:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
m_fArmed = true;
|
|
|
|
}
|
|
|
|
else if (!m_fArmed)
|
|
|
|
{
|
|
|
|
m_fArmed = true;
|
|
|
|
aeAcquireLock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void disarm()
|
|
|
|
{
|
|
|
|
serverAssert(m_fArmed);
|
|
|
|
m_fArmed = false;
|
|
|
|
aeReleaseLock();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isArmed() const
|
|
|
|
{
|
|
|
|
return m_fArmed;
|
|
|
|
}
|
|
|
|
|
2019-09-12 18:51:10 -04:00
|
|
|
void release()
|
|
|
|
{
|
|
|
|
m_fArmed = false;
|
|
|
|
}
|
|
|
|
|
2019-06-16 21:10:38 -04:00
|
|
|
~AeLocker()
|
|
|
|
{
|
|
|
|
if (m_fArmed)
|
|
|
|
aeReleaseLock();
|
|
|
|
}
|
|
|
|
};
|