From a4cb9ebc263d65b23426e9b6e5d0e71f6f11c51f Mon Sep 17 00:00:00 2001 From: dimitr Date: Tue, 28 Sep 2004 20:25:52 +0000 Subject: [PATCH] Added transaction lock timeouts and new TPB value. --- src/jrd/dfw.epp | 30 ++++++++++-------------------- src/jrd/ibase.h | 13 +++++++------ src/jrd/rlck.cpp | 16 ++++++++-------- src/jrd/tra.cpp | 28 +++++++++++++++++++++++----- src/jrd/tra.h | 3 +++ 5 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/jrd/dfw.epp b/src/jrd/dfw.epp index c10d1f28a0..f9859dadcc 100644 --- a/src/jrd/dfw.epp +++ b/src/jrd/dfw.epp @@ -2381,13 +2381,12 @@ static bool delete_index(thread_db* tdbb, SSHORT phase, DeferredWork* work, index = CMP_get_index_lock(tdbb, relation, id); if (index) { - const USHORT wait = - (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; // Try to clear trigger cache to release lock if (index->idl_count) MET_clear_cache(tdbb); if (index->idl_count || - !LCK_lock_non_blocking(tdbb, index->idl_lock, LCK_EX, wait)) + !LCK_lock_non_blocking(tdbb, index->idl_lock, LCK_EX, + transaction->getLockWait())) { ERR_post(isc_no_meta_update, isc_arg_gds, isc_obj_in_use, @@ -2530,7 +2529,6 @@ static bool delete_procedure( thread_db* tdbb, * **************************************/ jrd_prc* procedure; - USHORT wait; USHORT old_flags; SET_TDBB(tdbb); @@ -2545,9 +2543,8 @@ static bool delete_procedure( thread_db* tdbb, if (procedure->prc_existence_lock) { - wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; LCK_convert_non_blocking(tdbb, procedure->prc_existence_lock, - LCK_SR, wait); + LCK_SR, transaction->getLockWait()); } return false; @@ -2564,9 +2561,8 @@ static bool delete_procedure( thread_db* tdbb, if (procedure->prc_existence_lock) { - wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; if (!LCK_convert_non_blocking(tdbb, procedure->prc_existence_lock, - LCK_EX, wait)) + LCK_EX, transaction->getLockWait())) { ERR_post(isc_no_meta_update, isc_arg_gds, isc_obj_in_use, @@ -2645,7 +2641,7 @@ static bool delete_relation(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_req* request; jrd_rel* relation; Resource* rsc; - USHORT wait, view_count; + USHORT view_count; bool adjusted; SET_TDBB(tdbb); @@ -2661,9 +2657,8 @@ static bool delete_relation(thread_db* tdbb, SSHORT phase, DeferredWork* work, if (relation->rel_existence_lock) { - wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; LCK_convert_non_blocking(tdbb, relation->rel_existence_lock, - LCK_SR, wait); + LCK_SR, transaction->getLockWait()); } relation->rel_flags &= ~REL_deleting; @@ -2723,13 +2718,12 @@ static bool delete_relation(thread_db* tdbb, SSHORT phase, DeferredWork* work, } } - wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; if (relation->rel_use_count) MET_clear_cache(tdbb); if (relation->rel_use_count || (relation->rel_existence_lock && !LCK_convert_non_blocking(tdbb, relation->rel_existence_lock, - LCK_EX, wait))) + LCK_EX, transaction->getLockWait()))) { if (adjusted) { ++relation->rel_use_count; @@ -2761,7 +2755,7 @@ static bool delete_relation(thread_db* tdbb, SSHORT phase, DeferredWork* work, don't wait forever if something has gone awry and the sweep count doesn't run down. */ - for (wait = 0; wait < 60; wait++) + for (int wait = 0; wait < 60; wait++) { if (!relation->rel_sweep_count) { break; @@ -3830,7 +3824,6 @@ static bool modify_procedure( thread_db* tdbb, * **************************************/ jrd_prc* procedure; - USHORT wait; SET_TDBB(tdbb); @@ -3849,9 +3842,8 @@ static bool modify_procedure( thread_db* tdbb, if (procedure->prc_existence_lock) { - wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; LCK_convert_non_blocking(tdbb, procedure->prc_existence_lock, - LCK_SR, wait); + LCK_SR, transaction->getLockWait()); } return false; } @@ -3869,12 +3861,10 @@ static bool modify_procedure( thread_db* tdbb, if (procedure->prc_existence_lock) { - wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; - /* Let relation be deleted if only this transaction is using it */ if (!LCK_convert_non_blocking(tdbb, procedure->prc_existence_lock, - LCK_EX, wait)) + LCK_EX, transaction->getLockWait())) { ERR_post(isc_no_meta_update, isc_arg_gds, isc_obj_in_use, diff --git a/src/jrd/ibase.h b/src/jrd/ibase.h index 3122fc56fd..ec15e47011 100644 --- a/src/jrd/ibase.h +++ b/src/jrd/ibase.h @@ -33,7 +33,7 @@ * */ /* -$Id: ibase.h,v 1.87 2004-09-22 01:59:20 robocop Exp $ +$Id: ibase.h,v 1.88 2004-09-28 20:25:52 dimitr Exp $ */ #ifndef JRD_IBASE_H @@ -1292,12 +1292,13 @@ int ISC_EXPORT isc_get_client_minor_version (); #define isc_tpb_verb_time 12 #define isc_tpb_commit_time 13 #define isc_tpb_ignore_limbo 14 -#define isc_tpb_read_committed 15 -#define isc_tpb_autocommit 16 -#define isc_tpb_rec_version 17 -#define isc_tpb_no_rec_version 18 -#define isc_tpb_restart_requests 19 +#define isc_tpb_read_committed 15 +#define isc_tpb_autocommit 16 +#define isc_tpb_rec_version 17 +#define isc_tpb_no_rec_version 18 +#define isc_tpb_restart_requests 19 #define isc_tpb_no_auto_undo 20 +#define isc_tpb_lock_timeout 21 /************************/ diff --git a/src/jrd/rlck.cpp b/src/jrd/rlck.cpp index c6c494ad33..71ce1a91e9 100644 --- a/src/jrd/rlck.cpp +++ b/src/jrd/rlck.cpp @@ -257,11 +257,10 @@ Lock* RLCK_range_relation(jrd_tra* transaction, const USHORT level = LCK_PR; - const USHORT wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; - /* get lock */ - const USHORT result = LCK_lock_non_blocking(tdbb, lock, level, wait); + const USHORT result = + LCK_lock_non_blocking(tdbb, lock, level, transaction->getLockWait()); if (result) return lock; @@ -440,18 +439,19 @@ Lock* RLCK_reserve_relation(thread_db* tdbb, return lock; if (transaction->tra_flags & TRA_reserving) ERR_post(isc_unres_rel, isc_arg_string, relation->rel_name, 0); - const USHORT wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; /* get lock */ USHORT result; if (lock->lck_logical) - result = LCK_convert_non_blocking(NULL, lock, level, wait); + result = LCK_convert_non_blocking(NULL, lock, level, + transaction->getLockWait()); else - result = LCK_lock_non_blocking(NULL, lock, level, wait); + result = LCK_lock_non_blocking(NULL, lock, level, + transaction->getLockWait()); if (result) return lock; else { if (error_flag) - ERR_post((wait) ? isc_deadlock : isc_lock_conflict, 0); + ERR_post(transaction->getLockWait() ? isc_deadlock : isc_lock_conflict, 0); return NULL; } } @@ -964,7 +964,7 @@ static bool obtain_lock(jrd_tra* transaction, Lock* lock, USHORT lock_level) **************************************/ USHORT wait_flag; if (transaction) - wait_flag = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE; + wait_flag = transaction->getLockWait(); else wait_flag = FALSE; /* return if lock level OK and if the lock has not been released diff --git a/src/jrd/tra.cpp b/src/jrd/tra.cpp index 06444e894d..cd6a9ff8b8 100644 --- a/src/jrd/tra.cpp +++ b/src/jrd/tra.cpp @@ -90,9 +90,15 @@ static const SCHAR lock_types[] = }; #endif /* VMS */ +const int DEFAULT_LOCK_TIMEOUT = -1; + using namespace Jrd; using namespace Ods; +SSHORT jrd_tra::getLockWait() const +{ + return (tra_flags & TRA_nowait) ? 0 : -tra_lock_timeout; +} #ifdef SUPERSERVER_V2 static SLONG bump_transaction_id(thread_db*, WIN *); @@ -686,6 +692,7 @@ void TRA_init(thread_db* tdbb) jrd_tra* trans = FB_NEW_RPT(*dbb->dbb_permanent, 0) jrd_tra(*dbb->dbb_permanent); dbb->dbb_sys_trans = trans; + trans->tra_lock_timeout = DEFAULT_LOCK_TIMEOUT; trans->tra_flags |= TRA_system | TRA_ignore_limbo; trans->tra_pool = dbb->dbb_permanent; } @@ -939,6 +946,7 @@ jrd_tra* TRA_reconnect(thread_db* tdbb, const UCHAR* id, USHORT length) jrd_tra* trans = FB_NEW_RPT(*tdbb->getDefaultPool(), 0) jrd_tra(*tdbb->getDefaultPool()); trans->tra_pool = tdbb->getDefaultPool(); trans->tra_number = gds__vax_integer(id, length); + trans->tra_lock_timeout = DEFAULT_LOCK_TIMEOUT; trans->tra_flags |= TRA_prepared | TRA_reconnected | TRA_write; const UCHAR state = limbo_transaction(tdbb, trans->tra_number); @@ -1478,6 +1486,7 @@ jrd_tra* TRA_start(thread_db* tdbb, int tpb_length, const SCHAR* tpb) trans->tra_pool = temp->tra_pool; trans->tra_relation_locks = temp->tra_relation_locks; + trans->tra_lock_timeout = temp->tra_lock_timeout; trans->tra_flags = temp->tra_flags; trans->tra_number = number; trans->tra_top = number; @@ -1971,8 +1980,8 @@ int TRA_wait(thread_db* tdbb, jrd_tra* trans, SLONG number, bool wait) temp_lock.lck_key.lck_long = number; temp_lock.lck_owner = trans; - const USHORT wait_flag = (trans->tra_flags & TRA_nowait) ? FALSE : TRUE; - if (!LCK_lock_non_blocking(tdbb, &temp_lock, LCK_read, wait_flag)) + if (!LCK_lock_non_blocking(tdbb, &temp_lock, LCK_read, + trans->getLockWait())) return tra_active; LCK_release(tdbb, &temp_lock); @@ -2767,12 +2776,13 @@ static void transaction_options( if (!tpb_length) return; - USHORT wait = 1; const UCHAR* const end = tpb + tpb_length; if (*tpb != isc_tpb_version3 && *tpb != isc_tpb_version1) ERR_post(isc_bad_tpb_form, isc_arg_gds, isc_wrotpbver, 0); + transaction->tra_lock_timeout = DEFAULT_LOCK_TIMEOUT; + ++tpb; while (tpb < end) { @@ -2810,7 +2820,6 @@ static void transaction_options( break; case isc_tpb_nowait: - wait = 0; transaction->tra_flags |= TRA_nowait; break; @@ -2838,7 +2847,7 @@ static void transaction_options( USHORT l = *tpb++; if (l) { if (l >= sizeof(name)) { - TEXT text[128]; + TEXT text[BUFFER_TINY]; USHORT flags = 0; gds__msg_lookup(0, DYN_MSG_FAC, 159, sizeof(text), text, &flags); @@ -2893,6 +2902,14 @@ static void transaction_options( transaction->tra_flags |= TRA_restart_requests; break; + case isc_tpb_lock_timeout: + { + const USHORT l = *tpb++; + transaction->tra_lock_timeout = gds__vax_integer(tpb, l); + tpb += l; + break; + } + default: ERR_post(isc_bad_tpb_form, 0); } @@ -2912,6 +2929,7 @@ static void transaction_options( if (!lock) continue; USHORT level = lock->lck_logical; + const SSHORT wait = transaction->getLockWait(); if (level == LCK_none || LCK_lock_non_blocking(tdbb, lock, level, wait)) { diff --git a/src/jrd/tra.h b/src/jrd/tra.h index bd828da3f2..eb3db9958f 100644 --- a/src/jrd/tra.h +++ b/src/jrd/tra.h @@ -105,8 +105,11 @@ class jrd_tra : public pool_alloc_rpt traRpbList* tra_rpblist; /* active record_param's of given transaction */ UCHAR tra_use_count; /* use count for safe AST delivery */ UCHAR tra_callback_count; /* callback count for 'execute statement' */ + SSHORT tra_lock_timeout; /* in seconds, -1 infinite */ ULONG tra_next_blob_id; // ID of the previous blob or array created in this transaction UCHAR tra_transactions[1]; + + SSHORT getLockWait() const; }; const ULONG TRA_system = 1L; /* system transaction */