mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 00:03:03 +01:00
Fixed CORE-3686: Incorrect (zero) values are reported for "acquire blocks" and "mutex wait" counters in the fb_lock_print output.
This commit is contained in:
parent
15b739412a
commit
448f1871df
@ -221,6 +221,7 @@ LockManager::LockManager(const Firebird::string& id)
|
||||
m_process(NULL),
|
||||
m_processOffset(0),
|
||||
m_dbId(getPool(), id),
|
||||
m_localBlockage(false),
|
||||
m_acquireSpins(Config::getLockAcquireSpins()),
|
||||
m_memorySize(Config::getLockMemSize())
|
||||
#ifdef USE_SHMEM_EXT
|
||||
@ -239,7 +240,7 @@ LockManager::~LockManager()
|
||||
{
|
||||
const SRQ_PTR process_offset = m_processOffset;
|
||||
{ // guardian's scope
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
m_processOffset = 0;
|
||||
}
|
||||
|
||||
@ -395,7 +396,7 @@ bool LockManager::initializeOwner(thread_db* tdbb,
|
||||
**************************************/
|
||||
LOCK_TRACE(("LOCK_init (ownerid=%ld)\n", owner_id));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
// If everything is already initialized, just bump the use count
|
||||
|
||||
@ -427,7 +428,7 @@ void LockManager::shutdownOwner(thread_db* tdbb, SRQ_PTR* owner_offset)
|
||||
**************************************/
|
||||
LOCK_TRACE(("LOCK_fini(%ld)\n", *owner_offset));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
if (!m_header)
|
||||
return;
|
||||
@ -442,12 +443,12 @@ void LockManager::shutdownOwner(thread_db* tdbb, SRQ_PTR* owner_offset)
|
||||
|
||||
while (owner->own_ast_count)
|
||||
{
|
||||
m_localMutex.leave();
|
||||
{ // scope
|
||||
{ // checkout scope
|
||||
LocalCheckout checkout(this);
|
||||
Database::Checkout dco(tdbb->getDatabase());
|
||||
THREAD_SLEEP(10);
|
||||
}
|
||||
m_localMutex.enter();
|
||||
|
||||
owner = (own*) SRQ_ABS_PTR(offset); // Re-init after a potential remap
|
||||
}
|
||||
|
||||
@ -489,7 +490,7 @@ SRQ_PTR LockManager::enqueue(thread_db* tdbb,
|
||||
**************************************/
|
||||
LOCK_TRACE(("LOCK_enq (%ld)\n", parent_request));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
own* owner = (own*) SRQ_ABS_PTR(owner_offset);
|
||||
if (!owner_offset || !owner->own_count)
|
||||
@ -648,7 +649,7 @@ bool LockManager::convert(thread_db* tdbb,
|
||||
**************************************/
|
||||
LOCK_TRACE(("LOCK_convert (%d, %d)\n", type, lck_wait));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
lrq* request = get_request(request_offset);
|
||||
own* owner = (own*) SRQ_ABS_PTR(request->lrq_owner);
|
||||
@ -683,7 +684,7 @@ UCHAR LockManager::downgrade(thread_db* tdbb, const SRQ_PTR request_offset)
|
||||
**************************************/
|
||||
LOCK_TRACE(("LOCK_downgrade (%ld)\n", request_offset));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
lrq* request = get_request(request_offset);
|
||||
SRQ_PTR owner_offset = request->lrq_owner;
|
||||
@ -747,7 +748,7 @@ bool LockManager::dequeue(const SRQ_PTR request_offset)
|
||||
**************************************/
|
||||
LOCK_TRACE(("LOCK_deq (%ld)\n", request_offset));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
lrq* request = get_request(request_offset);
|
||||
const SRQ_PTR owner_offset = request->lrq_owner;
|
||||
@ -788,7 +789,7 @@ void LockManager::repost(thread_db* tdbb, lock_ast_t ast, void* arg, SRQ_PTR own
|
||||
|
||||
LOCK_TRACE(("LOCK_re_post(%ld)\n", owner_offset));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
acquire_shmem(owner_offset);
|
||||
|
||||
@ -849,7 +850,7 @@ bool LockManager::cancelWait(SRQ_PTR owner_offset)
|
||||
if (!owner_offset)
|
||||
return false;
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
acquire_shmem(DUMMY_OWNER);
|
||||
|
||||
@ -881,7 +882,7 @@ SLONG LockManager::queryData(SRQ_PTR parent_request, const USHORT series, const
|
||||
return 0;
|
||||
}
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
// Get root of lock hierarchy
|
||||
|
||||
@ -978,7 +979,7 @@ SLONG LockManager::readData(SRQ_PTR request_offset)
|
||||
**************************************/
|
||||
LOCK_TRACE(("LOCK_read_data(%ld)\n", request_offset));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
lrq* request = get_request(request_offset);
|
||||
acquire_shmem(request->lrq_owner);
|
||||
@ -1016,7 +1017,7 @@ SLONG LockManager::readData2(SRQ_PTR parent_request,
|
||||
**************************************/
|
||||
LOCK_TRACE(("LOCK_read_data2(%ld)\n", parent_request));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
acquire_shmem(owner_offset);
|
||||
|
||||
@ -1063,7 +1064,7 @@ SLONG LockManager::writeData(SRQ_PTR request_offset, SLONG data)
|
||||
**************************************/
|
||||
LOCK_TRACE(("LOCK_write_data (%ld)\n", request_offset));
|
||||
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
lrq* request = get_request(request_offset);
|
||||
acquire_shmem(request->lrq_owner);
|
||||
@ -1171,8 +1172,9 @@ void LockManager::acquire_shmem(SRQ_PTR owner_offset)
|
||||
fb_assert(!m_sharedFileCreated);
|
||||
|
||||
++m_header->lhb_acquires;
|
||||
if (prior_active > 0) {
|
||||
if (m_localBlockage || prior_active > 0) {
|
||||
++m_header->lhb_acquire_blocks;
|
||||
m_localBlockage = false;
|
||||
}
|
||||
|
||||
if (spins)
|
||||
@ -1474,17 +1476,21 @@ void LockManager::blocking_action(thread_db* tdbb,
|
||||
{
|
||||
owner->own_ast_count++;
|
||||
release_shmem(blocked_owner_offset);
|
||||
m_localMutex.leave();
|
||||
if (tdbb)
|
||||
{
|
||||
Database::Checkout dcoHolder(tdbb->getDatabase());
|
||||
(*routine)(arg);
|
||||
|
||||
{ // checkout scope
|
||||
LocalCheckout checkout(this);
|
||||
|
||||
if (tdbb)
|
||||
{
|
||||
Database::Checkout dcoHolder(tdbb->getDatabase());
|
||||
(*routine)(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*routine)(arg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*routine)(arg);
|
||||
}
|
||||
m_localMutex.enter();
|
||||
|
||||
acquire_shmem(blocked_owner_offset);
|
||||
owner = (own*) SRQ_ABS_PTR(blocking_owner_offset);
|
||||
owner->own_ast_count--;
|
||||
@ -1524,7 +1530,7 @@ void LockManager::blocking_action_thread()
|
||||
{
|
||||
SLONG value;
|
||||
{ // guardian's scope
|
||||
Firebird::MutexLockGuard guard(m_localMutex);
|
||||
LocalGuard guard(this);
|
||||
|
||||
// See if the main thread has requested us to go away
|
||||
if (!m_processOffset || m_process->prc_process_id != PID)
|
||||
@ -4010,18 +4016,19 @@ USHORT LockManager::wait_for_request(thread_db* tdbb, lrq* request, SSHORT lck_w
|
||||
// Re-initialize value each time thru the loop to make sure that the
|
||||
// semaphore looks 'un-poked'
|
||||
|
||||
m_localMutex.leave();
|
||||
LocalCheckout checkout(this);
|
||||
|
||||
{ // scope
|
||||
Firebird::ReadLockGuard guard(m_remapSync);
|
||||
owner = (own*) SRQ_ABS_PTR(owner_offset);
|
||||
++m_waitingOwners;
|
||||
}
|
||||
|
||||
{ // scope
|
||||
Database::Checkout dcoHolder(tdbb->getDatabase());
|
||||
ret = ISC_event_wait(&owner->own_wakeup, value, (timeout - current_time) * 1000000);
|
||||
--m_waitingOwners;
|
||||
}
|
||||
m_localMutex.enter();
|
||||
}
|
||||
|
||||
// We've woken up from the wait - now look around and see why we wokeup
|
||||
|
@ -308,6 +308,72 @@ class thread_db;
|
||||
|
||||
class LockManager : private Firebird::RefCounted, public Firebird::GlobalStorage
|
||||
{
|
||||
class LocalGuard
|
||||
{
|
||||
public:
|
||||
explicit LocalGuard(LockManager* lm)
|
||||
: m_lm(lm)
|
||||
{
|
||||
if (!m_lm->m_localMutex.tryEnter())
|
||||
{
|
||||
m_lm->m_localMutex.enter();
|
||||
m_lm->m_localBlockage = true;
|
||||
}
|
||||
}
|
||||
|
||||
~LocalGuard()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_lm->m_localMutex.leave();
|
||||
}
|
||||
catch (const Firebird::Exception&)
|
||||
{
|
||||
DtorException::devHalt();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Forbid copying
|
||||
LocalGuard(const LocalGuard&);
|
||||
LocalGuard& operator=(const LocalGuard&);
|
||||
|
||||
LockManager* m_lm;
|
||||
};
|
||||
|
||||
class LocalCheckout
|
||||
{
|
||||
public:
|
||||
explicit LocalCheckout(LockManager* lm)
|
||||
: m_lm(lm)
|
||||
{
|
||||
m_lm->m_localMutex.leave();
|
||||
}
|
||||
|
||||
~LocalCheckout()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!m_lm->m_localMutex.tryEnter())
|
||||
{
|
||||
m_lm->m_localMutex.enter();
|
||||
m_lm->m_localBlockage = true;
|
||||
}
|
||||
}
|
||||
catch (const Firebird::Exception&)
|
||||
{
|
||||
DtorException::devHalt();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Forbid copying
|
||||
LocalCheckout(const LocalCheckout&);
|
||||
LocalCheckout& operator=(const LocalCheckout&);
|
||||
|
||||
LockManager* m_lm;
|
||||
};
|
||||
|
||||
typedef Firebird::GenericMap<Firebird::Pair<Firebird::Left<Firebird::string, LockManager*> > > DbLockMgrMap;
|
||||
|
||||
static Firebird::GlobalPtr<DbLockMgrMap> g_lmMap;
|
||||
@ -426,6 +492,8 @@ private:
|
||||
|
||||
Firebird::string m_dbId;
|
||||
|
||||
bool m_localBlockage;
|
||||
|
||||
const ULONG m_acquireSpins;
|
||||
const ULONG m_memorySize;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user