mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 08:03:03 +01:00
Improvement CORE-3323 : Ability to cancel waiting in lock manager
This commit is contained in:
parent
cb34e0c6c9
commit
b2b911fe6c
161
src/jrd/jrd.cpp
161
src/jrd/jrd.cpp
@ -1583,6 +1583,7 @@ ISC_STATUS FB_CANCEL_OPERATION(ISC_STATUS* user_status, Attachment** handle, USH
|
|||||||
{
|
{
|
||||||
attachment->att_flags |= ATT_cancel_raise;
|
attachment->att_flags |= ATT_cancel_raise;
|
||||||
attachment->cancelExternalConnection(tdbb);
|
attachment->cancelExternalConnection(tdbb);
|
||||||
|
LCK_cancel_wait(attachment);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4033,84 +4034,24 @@ bool JRD_reschedule(thread_db* tdbb, SLONG quantum, bool punt)
|
|||||||
THREAD_YIELD();
|
THREAD_YIELD();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test various flags and unwind/throw if required.
|
try {
|
||||||
// But do that only if we're neither in the verb cleanup state
|
tdbb->checkCancelState(punt);
|
||||||
// nor currently detaching, as these actions should never be interrupted.
|
}
|
||||||
|
catch (const status_exception& ex)
|
||||||
if (!(tdbb->tdbb_flags & (TDBB_verb_cleanup | TDBB_detaching)))
|
|
||||||
{
|
{
|
||||||
// If database has been shutdown then get out
|
tdbb->tdbb_flags |= TDBB_sys_error;
|
||||||
|
|
||||||
Attachment* const attachment = tdbb->getAttachment();
|
const Arg::StatusVector status(ex.value());
|
||||||
jrd_tra* const transaction = tdbb->getTransaction();
|
|
||||||
jrd_req* const request = tdbb->getRequest();
|
|
||||||
|
|
||||||
try
|
if (punt)
|
||||||
{
|
{
|
||||||
if (attachment)
|
CCH_unwind(tdbb, false);
|
||||||
{
|
ERR_post(status);
|
||||||
if (attachment->att_flags & ATT_shutdown)
|
|
||||||
{
|
|
||||||
if (dbb->dbb_ast_flags & DBB_shutdown)
|
|
||||||
{
|
|
||||||
status_exception::raise(Arg::Gds(isc_shutdown) <<
|
|
||||||
Arg::Str(attachment->att_filename));
|
|
||||||
}
|
|
||||||
else if (!(tdbb->tdbb_flags & TDBB_shutdown_manager))
|
|
||||||
{
|
|
||||||
status_exception::raise(Arg::Gds(isc_att_shutdown));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a cancel has been raised, defer its acknowledgement
|
|
||||||
// when executing in the context of an internal request or
|
|
||||||
// the system transaction.
|
|
||||||
|
|
||||||
if ((attachment->att_flags & ATT_cancel_raise) &&
|
|
||||||
!(attachment->att_flags & ATT_cancel_disable))
|
|
||||||
{
|
|
||||||
if ((!request ||
|
|
||||||
!(request->req_flags & (req_internal | req_sys_trigger))) &&
|
|
||||||
(!transaction || !(transaction->tra_flags & TRA_system)))
|
|
||||||
{
|
|
||||||
attachment->att_flags &= ~ATT_cancel_raise;
|
|
||||||
status_exception::raise(Arg::Gds(isc_cancelled));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle request cancellation
|
|
||||||
|
|
||||||
if (transaction && (transaction->tra_flags & TRA_cancel_request))
|
|
||||||
{
|
|
||||||
transaction->tra_flags &= ~TRA_cancel_request;
|
|
||||||
status_exception::raise(Arg::Gds(isc_cancelled));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the thread state for already posted system errors. If any still persists,
|
|
||||||
// then someone tries to ignore our attempts to interrupt him. Let's insist.
|
|
||||||
|
|
||||||
if (tdbb->tdbb_flags & TDBB_sys_error)
|
|
||||||
{
|
|
||||||
status_exception::raise(Arg::Gds(isc_cancelled));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (const status_exception& ex)
|
else
|
||||||
{
|
{
|
||||||
tdbb->tdbb_flags |= TDBB_sys_error;
|
ERR_build_status(tdbb->tdbb_status_vector, status);
|
||||||
|
return true;
|
||||||
const Arg::StatusVector status(ex.value());
|
|
||||||
|
|
||||||
if (punt)
|
|
||||||
{
|
|
||||||
CCH_unwind(tdbb, false);
|
|
||||||
ERR_post(status);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERR_build_status(tdbb->tdbb_status_vector, status);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5785,6 +5726,7 @@ static unsigned int purge_transactions(thread_db* tdbb,
|
|||||||
if ((transaction->tra_flags & TRA_prepared) || (dbb->dbb_ast_flags & DBB_shutdown) ||
|
if ((transaction->tra_flags & TRA_prepared) || (dbb->dbb_ast_flags & DBB_shutdown) ||
|
||||||
(att_flags & ATT_shutdown))
|
(att_flags & ATT_shutdown))
|
||||||
{
|
{
|
||||||
|
EDS::Transaction::jrdTransactionEnd(tdbb, transaction, false, false, true);
|
||||||
TRA_release_transaction(tdbb, transaction);
|
TRA_release_transaction(tdbb, transaction);
|
||||||
}
|
}
|
||||||
else if (force_flag)
|
else if (force_flag)
|
||||||
@ -6235,6 +6177,81 @@ static THREAD_ENTRY_DECLARE shutdown_thread(THREAD_ENTRY_PARAM arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool thread_db::checkCancelState(bool punt)
|
||||||
|
{
|
||||||
|
// Test various flags and unwind/throw if required.
|
||||||
|
// But do that only if we're neither in the verb cleanup state
|
||||||
|
// nor currently detaching, as these actions should never be interrupted.
|
||||||
|
// Also don't break wait in LM if it is not safe.
|
||||||
|
|
||||||
|
if (tdbb_flags & (TDBB_verb_cleanup | TDBB_detaching | TDBB_wait_cancel_disable))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (attachment)
|
||||||
|
{
|
||||||
|
if (attachment->att_flags & ATT_shutdown)
|
||||||
|
{
|
||||||
|
if (database->dbb_ast_flags & DBB_shutdown)
|
||||||
|
{
|
||||||
|
if (!punt)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
status_exception::raise(Arg::Gds(isc_shutdown) <<
|
||||||
|
Arg::Str(attachment->att_filename));
|
||||||
|
}
|
||||||
|
else if (!(tdbb_flags & TDBB_shutdown_manager))
|
||||||
|
{
|
||||||
|
if (!punt)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
status_exception::raise(Arg::Gds(isc_att_shutdown));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a cancel has been raised, defer its acknowledgement
|
||||||
|
// when executing in the context of an internal request or
|
||||||
|
// the system transaction.
|
||||||
|
|
||||||
|
if ((attachment->att_flags & ATT_cancel_raise) &&
|
||||||
|
!(attachment->att_flags & ATT_cancel_disable))
|
||||||
|
{
|
||||||
|
if ((!request ||
|
||||||
|
!(request->req_flags & (req_internal | req_sys_trigger))) &&
|
||||||
|
(!transaction || !(transaction->tra_flags & TRA_system)))
|
||||||
|
{
|
||||||
|
if (!punt)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
attachment->att_flags &= ~ATT_cancel_raise;
|
||||||
|
status_exception::raise(Arg::Gds(isc_cancelled));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle request cancellation
|
||||||
|
|
||||||
|
if (transaction && (transaction->tra_flags & TRA_cancel_request))
|
||||||
|
{
|
||||||
|
if (!punt)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
transaction->tra_flags &= ~TRA_cancel_request;
|
||||||
|
status_exception::raise(Arg::Gds(isc_cancelled));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the thread state for already posted system errors. If any still persists,
|
||||||
|
// then someone tries to ignore our attempts to interrupt him. Let's insist.
|
||||||
|
|
||||||
|
if (tdbb_flags & TDBB_sys_error)
|
||||||
|
{
|
||||||
|
if (!punt)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
status_exception::raise(Arg::Gds(isc_cancelled));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void thread_db::setTransaction(jrd_tra* val)
|
void thread_db::setTransaction(jrd_tra* val)
|
||||||
{
|
{
|
||||||
|
@ -313,6 +313,7 @@ public:
|
|||||||
ULONG att_flags; // Flags describing the state of the attachment
|
ULONG att_flags; // Flags describing the state of the attachment
|
||||||
SSHORT att_charset; // user's charset specified in dpb
|
SSHORT att_charset; // user's charset specified in dpb
|
||||||
Lock* att_long_locks; // outstanding two phased locks
|
Lock* att_long_locks; // outstanding two phased locks
|
||||||
|
Lock* att_wait_lock; // lock at which attachment waits currently
|
||||||
vec<Lock*>* att_compatibility_table; // hash table of compatible locks
|
vec<Lock*>* att_compatibility_table; // hash table of compatible locks
|
||||||
vcl* att_val_errors;
|
vcl* att_val_errors;
|
||||||
Firebird::PathName att_working_directory; // Current working directory is cached
|
Firebird::PathName att_working_directory; // Current working directory is cached
|
||||||
@ -778,6 +779,8 @@ public:
|
|||||||
//attStat->bumpValue(index, relation_id);
|
//attStat->bumpValue(index, relation_id);
|
||||||
//dbbStat->bumpValue(index, relation_id);
|
//dbbStat->bumpValue(index, relation_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool checkCancelState(bool punt);
|
||||||
};
|
};
|
||||||
|
|
||||||
// tdbb_flags
|
// tdbb_flags
|
||||||
@ -793,6 +796,7 @@ const USHORT TDBB_sys_error = 128; // error shouldn't be handled by the loope
|
|||||||
const USHORT TDBB_verb_cleanup = 256; // verb cleanup is in progress
|
const USHORT TDBB_verb_cleanup = 256; // verb cleanup is in progress
|
||||||
const USHORT TDBB_use_db_page_space = 512; // use database (not temporary) page space in GTT operations
|
const USHORT TDBB_use_db_page_space = 512; // use database (not temporary) page space in GTT operations
|
||||||
const USHORT TDBB_detaching = 1024; // detach is in progress
|
const USHORT TDBB_detaching = 1024; // detach is in progress
|
||||||
|
const USHORT TDBB_wait_cancel_disable = 2048; // don't cancel current waiting operation
|
||||||
|
|
||||||
|
|
||||||
class ThreadContextHolder
|
class ThreadContextHolder
|
||||||
|
@ -211,6 +211,61 @@ inline bool checkLock(const Lock* l)
|
|||||||
#define LCK_CHECK_LOCK(x) true // nothing
|
#define LCK_CHECK_LOCK(x) true // nothing
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// This class is used as a guard around long waiting call into LM and have
|
||||||
|
// two purposes :
|
||||||
|
// - set and restore att_wait_lock while waiting inside the LM
|
||||||
|
// - set or clear and restore TDBB_wait_cancel_disable flag in dependence
|
||||||
|
// of safety of cancelling lock waiting. Currently we can safely cancel
|
||||||
|
// only LCK_tra locks
|
||||||
|
|
||||||
|
class WaitCancelGuard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WaitCancelGuard(thread_db* tdbb, Lock* lock, int wait) :
|
||||||
|
m_tdbb(tdbb),
|
||||||
|
m_save_lock(NULL)
|
||||||
|
{
|
||||||
|
Attachment* att = m_tdbb->getAttachment();
|
||||||
|
m_save_lock = att->att_wait_lock;
|
||||||
|
|
||||||
|
m_cancel_disabled = (m_tdbb->tdbb_flags & TDBB_wait_cancel_disable);
|
||||||
|
m_tdbb->tdbb_flags |= TDBB_wait_cancel_disable;
|
||||||
|
|
||||||
|
if (!wait)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (lock->lck_type)
|
||||||
|
{
|
||||||
|
case LCK_tra:
|
||||||
|
m_tdbb->tdbb_flags &= ~TDBB_wait_cancel_disable;
|
||||||
|
att->att_wait_lock = lock;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~WaitCancelGuard()
|
||||||
|
{
|
||||||
|
Attachment* att = m_tdbb->getAttachment();
|
||||||
|
att->att_wait_lock = m_save_lock;
|
||||||
|
|
||||||
|
if (m_cancel_disabled)
|
||||||
|
m_tdbb->tdbb_flags |= TDBB_wait_cancel_disable;
|
||||||
|
else
|
||||||
|
m_tdbb->tdbb_flags &= ~TDBB_wait_cancel_disable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
thread_db* m_tdbb;
|
||||||
|
Lock* m_save_lock;
|
||||||
|
bool m_cancel_disabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
void LCK_assert(thread_db* tdbb, Lock* lock)
|
void LCK_assert(thread_db* tdbb, Lock* lock)
|
||||||
{
|
{
|
||||||
@ -259,6 +314,7 @@ bool LCK_convert(thread_db* tdbb, Lock* lock, USHORT level, SSHORT wait)
|
|||||||
Attachment* const old_attachment = lock->lck_attachment;
|
Attachment* const old_attachment = lock->lck_attachment;
|
||||||
set_lock_attachment(lock, tdbb->getAttachment());
|
set_lock_attachment(lock, tdbb->getAttachment());
|
||||||
|
|
||||||
|
WaitCancelGuard guard(tdbb, lock, wait);
|
||||||
const bool result = CONVERT(tdbb, lock, level, wait);
|
const bool result = CONVERT(tdbb, lock, level, wait);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
@ -270,6 +326,7 @@ bool LCK_convert(thread_db* tdbb, Lock* lock, USHORT level, SSHORT wait)
|
|||||||
case isc_deadlock:
|
case isc_deadlock:
|
||||||
case isc_lock_conflict:
|
case isc_lock_conflict:
|
||||||
case isc_lock_timeout:
|
case isc_lock_timeout:
|
||||||
|
tdbb->checkCancelState(true);
|
||||||
return false;
|
return false;
|
||||||
case isc_lockmanerr:
|
case isc_lockmanerr:
|
||||||
dbb->dbb_flags |= DBB_bugcheck;
|
dbb->dbb_flags |= DBB_bugcheck;
|
||||||
@ -316,6 +373,27 @@ bool LCK_convert_opt(thread_db* tdbb, Lock* lock, USHORT level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LCK_cancel_wait(Attachment* attachment)
|
||||||
|
{
|
||||||
|
/**************************************
|
||||||
|
*
|
||||||
|
* L C K _ c a n c e l _ w a i t
|
||||||
|
*
|
||||||
|
**************************************
|
||||||
|
*
|
||||||
|
* Functional description
|
||||||
|
* Try to cancel waiting of attachment inside the LM
|
||||||
|
*
|
||||||
|
**************************************/
|
||||||
|
Database *dbb = attachment->att_database;
|
||||||
|
|
||||||
|
if (attachment->att_wait_lock)
|
||||||
|
return dbb->dbb_lock_mgr->cancelWait(attachment->att_wait_lock->lck_owner_handle);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LCK_downgrade(thread_db* tdbb, Lock* lock)
|
void LCK_downgrade(thread_db* tdbb, Lock* lock)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
@ -535,6 +613,7 @@ bool LCK_lock(thread_db* tdbb, Lock* lock, USHORT level, SSHORT wait)
|
|||||||
Database* dbb = lock->lck_dbb;
|
Database* dbb = lock->lck_dbb;
|
||||||
set_lock_attachment(lock, tdbb->getAttachment());
|
set_lock_attachment(lock, tdbb->getAttachment());
|
||||||
|
|
||||||
|
WaitCancelGuard guard(tdbb, lock, wait);
|
||||||
ENQUEUE(tdbb, lock, level, wait);
|
ENQUEUE(tdbb, lock, level, wait);
|
||||||
fb_assert(LCK_CHECK_LOCK(lock));
|
fb_assert(LCK_CHECK_LOCK(lock));
|
||||||
if (!lock->lck_id)
|
if (!lock->lck_id)
|
||||||
@ -548,6 +627,7 @@ bool LCK_lock(thread_db* tdbb, Lock* lock, USHORT level, SSHORT wait)
|
|||||||
case isc_deadlock:
|
case isc_deadlock:
|
||||||
case isc_lock_conflict:
|
case isc_lock_conflict:
|
||||||
case isc_lock_timeout:
|
case isc_lock_timeout:
|
||||||
|
tdbb->checkCancelState(true);
|
||||||
return false;
|
return false;
|
||||||
case isc_lockmanerr:
|
case isc_lockmanerr:
|
||||||
dbb->dbb_flags |= DBB_bugcheck;
|
dbb->dbb_flags |= DBB_bugcheck;
|
||||||
|
@ -32,6 +32,7 @@ namespace Jrd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LCK_assert(Jrd::thread_db*, Jrd::Lock*);
|
void LCK_assert(Jrd::thread_db*, Jrd::Lock*);
|
||||||
|
bool LCK_cancel_wait(Jrd::Attachment*);
|
||||||
bool LCK_convert(Jrd::thread_db*, Jrd::Lock*, USHORT, SSHORT);
|
bool LCK_convert(Jrd::thread_db*, Jrd::Lock*, USHORT, SSHORT);
|
||||||
bool LCK_convert_opt(Jrd::thread_db*, Jrd::Lock*, USHORT);
|
bool LCK_convert_opt(Jrd::thread_db*, Jrd::Lock*, USHORT);
|
||||||
void LCK_downgrade(Jrd::thread_db*, Jrd::Lock*);
|
void LCK_downgrade(Jrd::thread_db*, Jrd::Lock*);
|
||||||
|
@ -2044,6 +2044,7 @@ static int blocking_ast_attachment(void* ast_object)
|
|||||||
|
|
||||||
attachment->att_flags |= ATT_shutdown;
|
attachment->att_flags |= ATT_shutdown;
|
||||||
attachment->cancelExternalConnection(tdbb);
|
attachment->cancelExternalConnection(tdbb);
|
||||||
|
LCK_cancel_wait(attachment);
|
||||||
|
|
||||||
JRD_shutdown_attachments(dbb);
|
JRD_shutdown_attachments(dbb);
|
||||||
|
|
||||||
|
@ -563,6 +563,7 @@ static bool shutdown_locks(thread_db* tdbb, SSHORT flag)
|
|||||||
{
|
{
|
||||||
attachment->att_flags |= ATT_shutdown;
|
attachment->att_flags |= ATT_shutdown;
|
||||||
attachment->cancelExternalConnection(tdbb);
|
attachment->cancelExternalConnection(tdbb);
|
||||||
|
LCK_cancel_wait(attachment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1989,6 +1989,7 @@ static int blocking_ast_transaction(void* ast_object)
|
|||||||
transaction->tra_flags |= TRA_cancel_request;
|
transaction->tra_flags |= TRA_cancel_request;
|
||||||
|
|
||||||
att->cancelExternalConnection(tdbb);
|
att->cancelExternalConnection(tdbb);
|
||||||
|
LCK_cancel_wait(att);
|
||||||
}
|
}
|
||||||
catch (const Firebird::Exception&)
|
catch (const Firebird::Exception&)
|
||||||
{} // no-op
|
{} // no-op
|
||||||
|
@ -829,6 +829,38 @@ void LockManager::repost(thread_db* tdbb, lock_ast_t ast, void* arg, SRQ_PTR own
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LockManager::cancelWait(SRQ_PTR owner_offset)
|
||||||
|
{
|
||||||
|
/**************************************
|
||||||
|
*
|
||||||
|
* c a n c e l W a i t
|
||||||
|
*
|
||||||
|
**************************************
|
||||||
|
*
|
||||||
|
* Functional description
|
||||||
|
* Wakeup waiting owner to make it check if wait should be cancelled.
|
||||||
|
* As this routine could be called asyncronous, take extra care and
|
||||||
|
* don't trust the input params blindly.
|
||||||
|
*
|
||||||
|
**************************************/
|
||||||
|
LOCK_TRACE(("cancelWait (%ld)\n", owner_offset));
|
||||||
|
|
||||||
|
if (!owner_offset)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Firebird::MutexLockGuard guard(m_localMutex);
|
||||||
|
|
||||||
|
acquire_shmem(DUMMY_OWNER);
|
||||||
|
|
||||||
|
own* owner = (own*) SRQ_ABS_PTR(owner_offset);
|
||||||
|
if (owner->own_type == type_own)
|
||||||
|
post_wakeup(owner);
|
||||||
|
|
||||||
|
release_shmem(DUMMY_OWNER);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SLONG LockManager::queryData(SRQ_PTR parent_request, const USHORT series, const USHORT aggregate)
|
SLONG LockManager::queryData(SRQ_PTR parent_request, const USHORT series, const USHORT aggregate)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
@ -1196,7 +1228,7 @@ void LockManager::acquire_shmem(SRQ_PTR owner_offset)
|
|||||||
// the lock mutex. In that event, lets see if there is any unfinished work
|
// the lock mutex. In that event, lets see if there is any unfinished work
|
||||||
// left around that we need to finish up.
|
// left around that we need to finish up.
|
||||||
|
|
||||||
if (prior_active)
|
if (prior_active > 0)
|
||||||
{
|
{
|
||||||
post_history(his_active, owner_offset, prior_active, (SRQ_PTR) 0, false);
|
post_history(his_active, owner_offset, prior_active, (SRQ_PTR) 0, false);
|
||||||
shb* const recover = (shb*) SRQ_ABS_PTR(m_header->lhb_secondary);
|
shb* const recover = (shb*) SRQ_ABS_PTR(m_header->lhb_secondary);
|
||||||
@ -4033,7 +4065,9 @@ USHORT LockManager::wait_for_request(thread_db* tdbb, lrq* request, SSHORT lck_w
|
|||||||
// See if we've waited beyond the lock timeout -
|
// See if we've waited beyond the lock timeout -
|
||||||
// if so we mark our own request as rejected
|
// if so we mark our own request as rejected
|
||||||
|
|
||||||
if (lck_wait < 0 && lock_timeout <= current_time)
|
const bool cancelled = tdbb->checkCancelState(false);
|
||||||
|
|
||||||
|
if (cancelled || lck_wait < 0 && lock_timeout <= current_time)
|
||||||
{
|
{
|
||||||
// We're going to reject our lock - it's the callers responsibility
|
// We're going to reject our lock - it's the callers responsibility
|
||||||
// to do cleanup and make sure post_pending() is called to wakeup
|
// to do cleanup and make sure post_pending() is called to wakeup
|
||||||
@ -4041,6 +4075,7 @@ USHORT LockManager::wait_for_request(thread_db* tdbb, lrq* request, SSHORT lck_w
|
|||||||
request->lrq_flags |= LRQ_rejected;
|
request->lrq_flags |= LRQ_rejected;
|
||||||
request->lrq_flags &= ~LRQ_pending;
|
request->lrq_flags &= ~LRQ_pending;
|
||||||
lock->lbl_pending_lrq_count--;
|
lock->lbl_pending_lrq_count--;
|
||||||
|
|
||||||
// and test - may be timeout due to missing process to deliver request
|
// and test - may be timeout due to missing process to deliver request
|
||||||
probe_processes();
|
probe_processes();
|
||||||
release_shmem(owner_offset);
|
release_shmem(owner_offset);
|
||||||
|
@ -329,6 +329,7 @@ public:
|
|||||||
bool dequeue(const SRQ_PTR);
|
bool dequeue(const SRQ_PTR);
|
||||||
|
|
||||||
void repost(thread_db*, lock_ast_t, void*, SRQ_PTR);
|
void repost(thread_db*, lock_ast_t, void*, SRQ_PTR);
|
||||||
|
bool cancelWait(SRQ_PTR);
|
||||||
|
|
||||||
SLONG queryData(SRQ_PTR, const USHORT, const USHORT);
|
SLONG queryData(SRQ_PTR, const USHORT, const USHORT);
|
||||||
SLONG readData(SRQ_PTR);
|
SLONG readData(SRQ_PTR);
|
||||||
|
Loading…
Reference in New Issue
Block a user