mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03:02 +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
4cd4649691
commit
0c02c039e4
@ -8657,7 +8657,7 @@ bool TimeoutTimer::expired() const
|
||||
return false;
|
||||
|
||||
const SINT64 t = currTime();
|
||||
return t > m_start + m_value;
|
||||
return t >= m_start + m_value;
|
||||
}
|
||||
|
||||
unsigned int TimeoutTimer::timeToExpire() const
|
||||
@ -8838,6 +8838,24 @@ void thread_db::reschedule()
|
||||
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
|
||||
|
||||
|
||||
|
@ -655,6 +655,10 @@ public:
|
||||
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)
|
||||
{
|
||||
if (tdbb_bdbs.isEmpty()) {
|
||||
|
@ -56,7 +56,6 @@
|
||||
using namespace Jrd;
|
||||
using namespace Firebird;
|
||||
|
||||
static SSHORT adjust_wait(thread_db* tdbb, SSHORT wait);
|
||||
static void bug_lck(const TEXT*);
|
||||
static bool compatible(const Lock*, const Lock*, USHORT);
|
||||
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);
|
||||
FbLocalStatus statusVector;
|
||||
|
||||
wait = adjust_wait(tdbb, wait);
|
||||
const bool result = CONVERT(tdbb, &statusVector, lock, level, wait);
|
||||
|
||||
if (!result)
|
||||
@ -672,7 +670,6 @@ bool LCK_lock(thread_db* tdbb, Lock* lock, USHORT level, SSHORT wait)
|
||||
WaitCancelGuard guard(tdbb, lock, wait);
|
||||
FbLocalStatus statusVector;
|
||||
|
||||
wait = adjust_wait(tdbb, wait);
|
||||
ENQUEUE(tdbb, &statusVector, lock, level, wait);
|
||||
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)
|
||||
{
|
||||
/**************************************
|
||||
|
@ -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
|
||||
|
||||
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
|
||||
|
||||
@ -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
|
||||
// do a deadlock scan
|
||||
deadlock_timeout = current_time + scan_interval;
|
||||
deadlock_timeout = current_time + tdbb->adjustWait(scan_interval);
|
||||
|
||||
// Handle lock event first
|
||||
if (ret == FB_SUCCESS)
|
||||
|
Loading…
Reference in New Issue
Block a user