mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 00:03:03 +01:00
Fixed bug CORE-2698 : Infinite wait in LocksCache::get
This commit is contained in:
parent
20cc44d4d3
commit
7a6ea06189
@ -67,15 +67,13 @@ public:
|
|||||||
return reinterpret_cast<UCHAR*> (&cached_lock->lck_key);
|
return reinterpret_cast<UCHAR*> (&cached_lock->lck_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLockKey(thread_db *tdbb, const UCHAR* key)
|
bool setLockKey(thread_db *tdbb, const UCHAR* key)
|
||||||
{
|
{
|
||||||
while (!tryReleaseLock(tdbb))
|
if (!tryReleaseLock(tdbb))
|
||||||
{
|
return false;
|
||||||
lock(tdbb, LCK_write, LCK_WAIT);
|
|
||||||
unlock(tdbb, LCK_write);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&cached_lock->lck_key, key, cached_lock->lck_length);
|
memcpy(&cached_lock->lck_key, key, cached_lock->lck_length);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const KeyHolder generate(const void*, const CachedLock* lock) {
|
static const KeyHolder generate(const void*, const CachedLock* lock) {
|
||||||
@ -154,17 +152,40 @@ GlobalRWLock* LocksCache<LockClass>::get(thread_db *tdbb, const UCHAR* key)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
QUE que_inst = m_lru.que_backward;
|
QUE que_inst = m_lru.que_backward;
|
||||||
QUE_DELETE((*que_inst));
|
int tries = MIN(m_capacity / 2, 16);
|
||||||
lock = (LockClass*) ((SCHAR*) que_inst - OFFSET (LockClass*, m_lru));
|
while (true)
|
||||||
|
{
|
||||||
|
lock = (LockClass*) ((SCHAR*) que_inst - OFFSET (LockClass*, m_lru));
|
||||||
|
|
||||||
bool found = (m_sortedLocks.find(KeyHolder(lock->getLockKey(), m_lockLen), pos));
|
bool found = (m_sortedLocks.find(KeyHolder(lock->getLockKey(), m_lockLen), pos));
|
||||||
fb_assert(found);
|
fb_assert(found);
|
||||||
|
|
||||||
m_sortedLocks.remove(pos);
|
if (lock->setLockKey(tdbb, key))
|
||||||
lock->setLockKey(tdbb, key);
|
{
|
||||||
|
m_sortedLocks.remove(pos);
|
||||||
|
QUE_DELETE((*que_inst));
|
||||||
|
|
||||||
found = (m_sortedLocks.find(KeyHolder(key, m_lockLen), pos));
|
found = (m_sortedLocks.find(KeyHolder(key, m_lockLen), pos));
|
||||||
fb_assert(!found);
|
fb_assert(!found);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (tries == 0)
|
||||||
|
{
|
||||||
|
m_capacity++;
|
||||||
|
lock = FB_NEW (m_pool) LockClass(tdbb, m_pool, m_lockType, m_lockLen, key);
|
||||||
|
found = (m_sortedLocks.find(KeyHolder(key, m_lockLen), pos));
|
||||||
|
fb_assert(!found);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
que_inst = que_inst->que_backward;
|
||||||
|
tries--;
|
||||||
|
// move busy lock to the head of LRU queue
|
||||||
|
QUE_DELETE(lock->m_lru);
|
||||||
|
QUE_INSERT(m_lru, lock->m_lru);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_sortedLocks.insert(pos, lock);
|
m_sortedLocks.insert(pos, lock);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user