mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 08:03:03 +01:00
Fixed bug #6802 : When the statement timeout is set, it causes the lock manager to delay reporting deadlocks until timeout is expired
This commit is contained in:
parent
b9017d6909
commit
721e2e7c7d
@ -8657,7 +8657,7 @@ bool TimeoutTimer::expired() const
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const SINT64 t = currTime();
|
const SINT64 t = currTime();
|
||||||
return t > m_start + m_value;
|
return t >= m_start + m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int TimeoutTimer::timeToExpire() const
|
unsigned int TimeoutTimer::timeToExpire() const
|
||||||
@ -8838,6 +8838,24 @@ void thread_db::reschedule()
|
|||||||
tdbb_quantum = (tdbb_flags & TDBB_sweeper) ? SWEEP_QUANTUM : QUANTUM;
|
tdbb_quantum = (tdbb_flags & TDBB_sweeper) ? SWEEP_QUANTUM : QUANTUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SLONG thread_db::adjustWait(SLONG wait) const
|
||||||
|
{
|
||||||
|
if ((wait == 0) || (tdbb_flags & TDBB_wait_cancel_disable) || !tdbb_reqTimer)
|
||||||
|
return wait;
|
||||||
|
|
||||||
|
const unsigned int tout = tdbb_reqTimer->timeToExpire();
|
||||||
|
SLONG t;
|
||||||
|
if (tout < MAX_SSHORT * 1000)
|
||||||
|
t = (tout + 999) / 1000;
|
||||||
|
else
|
||||||
|
t = MAX_SSHORT;
|
||||||
|
|
||||||
|
if (wait > t)
|
||||||
|
return t;
|
||||||
|
|
||||||
|
return wait;
|
||||||
|
}
|
||||||
|
|
||||||
// end thread_db methods
|
// end thread_db methods
|
||||||
|
|
||||||
|
|
||||||
|
@ -655,6 +655,10 @@ public:
|
|||||||
return tdbb_reqTimer;
|
return tdbb_reqTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns minimum of passed wait timeout and time to expiration of reqTimer.
|
||||||
|
// Timer value is rounded to the upper whole second.
|
||||||
|
SLONG adjustWait(SLONG wait) const;
|
||||||
|
|
||||||
void registerBdb(BufferDesc* bdb)
|
void registerBdb(BufferDesc* bdb)
|
||||||
{
|
{
|
||||||
if (tdbb_bdbs.isEmpty()) {
|
if (tdbb_bdbs.isEmpty()) {
|
||||||
|
@ -56,7 +56,6 @@
|
|||||||
using namespace Jrd;
|
using namespace Jrd;
|
||||||
using namespace Firebird;
|
using namespace Firebird;
|
||||||
|
|
||||||
static SSHORT adjust_wait(thread_db* tdbb, SSHORT wait);
|
|
||||||
static void bug_lck(const TEXT*);
|
static void bug_lck(const TEXT*);
|
||||||
static bool compatible(const Lock*, const Lock*, USHORT);
|
static bool compatible(const Lock*, const Lock*, USHORT);
|
||||||
static void enqueue(thread_db*, CheckStatusWrapper*, Lock*, USHORT, SSHORT);
|
static void enqueue(thread_db*, CheckStatusWrapper*, Lock*, USHORT, SSHORT);
|
||||||
@ -344,7 +343,6 @@ bool LCK_convert(thread_db* tdbb, Lock* lock, USHORT level, SSHORT wait)
|
|||||||
WaitCancelGuard guard(tdbb, lock, wait);
|
WaitCancelGuard guard(tdbb, lock, wait);
|
||||||
FbLocalStatus statusVector;
|
FbLocalStatus statusVector;
|
||||||
|
|
||||||
wait = adjust_wait(tdbb, wait);
|
|
||||||
const bool result = CONVERT(tdbb, &statusVector, lock, level, wait);
|
const bool result = CONVERT(tdbb, &statusVector, lock, level, wait);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
@ -672,7 +670,6 @@ bool LCK_lock(thread_db* tdbb, Lock* lock, USHORT level, SSHORT wait)
|
|||||||
WaitCancelGuard guard(tdbb, lock, wait);
|
WaitCancelGuard guard(tdbb, lock, wait);
|
||||||
FbLocalStatus statusVector;
|
FbLocalStatus statusVector;
|
||||||
|
|
||||||
wait = adjust_wait(tdbb, wait);
|
|
||||||
ENQUEUE(tdbb, &statusVector, lock, level, wait);
|
ENQUEUE(tdbb, &statusVector, lock, level, wait);
|
||||||
fb_assert(LCK_CHECK_LOCK(lock));
|
fb_assert(LCK_CHECK_LOCK(lock));
|
||||||
|
|
||||||
@ -872,40 +869,6 @@ void LCK_write_data(thread_db* tdbb, Lock* lock, LOCK_DATA_T data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SSHORT adjust_wait(thread_db* tdbb, SSHORT wait)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* a d j u s t _ w a i t
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* If wait is cancellable and if statement timer was started - calc new wait
|
|
||||||
* time to ensure it will not take longer than rest of timeout.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
if ((wait == LCK_NO_WAIT) || (tdbb->tdbb_flags & TDBB_wait_cancel_disable) || !tdbb->getTimeoutTimer())
|
|
||||||
return wait;
|
|
||||||
|
|
||||||
unsigned int tout = tdbb->getTimeoutTimer()->timeToExpire();
|
|
||||||
if (tout > 0)
|
|
||||||
{
|
|
||||||
SSHORT t;
|
|
||||||
if (tout < 1000)
|
|
||||||
t = 1;
|
|
||||||
else if (tout < MAX_SSHORT * 1000)
|
|
||||||
t = (tout + 999) / 1000;
|
|
||||||
else
|
|
||||||
t = MAX_SSHORT;
|
|
||||||
|
|
||||||
if ((wait == LCK_WAIT) || (-wait > t))
|
|
||||||
return -t;
|
|
||||||
}
|
|
||||||
return wait;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void bug_lck(const TEXT* string)
|
static void bug_lck(const TEXT* string)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
|
@ -3765,7 +3765,7 @@ void LockManager::wait_for_request(thread_db* tdbb, lrq* request, SSHORT lck_wai
|
|||||||
// out the time when the lock request will timeout
|
// out the time when the lock request will timeout
|
||||||
|
|
||||||
const time_t lock_timeout = (lck_wait < 0) ? current_time + (-lck_wait) : 0;
|
const time_t lock_timeout = (lck_wait < 0) ? current_time + (-lck_wait) : 0;
|
||||||
time_t deadlock_timeout = current_time + scan_interval;
|
time_t deadlock_timeout = current_time + tdbb->adjustWait(scan_interval);
|
||||||
|
|
||||||
// Wait in a loop until the lock becomes available
|
// Wait in a loop until the lock becomes available
|
||||||
|
|
||||||
@ -3890,7 +3890,7 @@ void LockManager::wait_for_request(thread_db* tdbb, lrq* request, SSHORT lck_wai
|
|||||||
|
|
||||||
// We're going to do some real work - reset when we next want to
|
// We're going to do some real work - reset when we next want to
|
||||||
// do a deadlock scan
|
// do a deadlock scan
|
||||||
deadlock_timeout = current_time + scan_interval;
|
deadlock_timeout = current_time + tdbb->adjustWait(scan_interval);
|
||||||
|
|
||||||
// Handle lock event first
|
// Handle lock event first
|
||||||
if (ret == FB_SUCCESS)
|
if (ret == FB_SUCCESS)
|
||||||
|
Loading…
Reference in New Issue
Block a user