8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 10:43:03 +01:00

Fix several mostly DDL-related coredumps and locking failures

This commit is contained in:
skidder 2002-09-27 22:59:24 +00:00
parent bb6521ee61
commit 0518ca14a3
6 changed files with 103 additions and 14 deletions

View File

@ -30,7 +30,7 @@
* This closes the heart of SF Bug #518282.
*/
/*
$Id: cmp.cpp,v 1.12 2002-09-26 18:13:02 skidder Exp $
$Id: cmp.cpp,v 1.13 2002-09-27 22:59:23 skidder Exp $
*/
#include "firebird.h"
@ -1644,6 +1644,7 @@ IDL DLL_EXPORT CMP_get_index_lock(TDBB tdbb, REL relation, USHORT id)
relation->rel_index_locks = index;
index->idl_relation = relation;
index->idl_id = id;
index->idl_count = 0;
index->idl_lock = lock = FB_NEW_RPT(*dbb->dbb_permanent, 0) lck;
lock->lck_parent = dbb->dbb_lock;

View File

@ -2290,6 +2290,9 @@ static bool delete_index(TDBB tdbb, SSHORT phase, DFW work, TRA transaction)
if (index)
{
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))
{
@ -2775,6 +2778,15 @@ static bool delete_relation(TDBB tdbb, SSHORT phase, DFW work, TRA transaction)
relation->rel_name = NULL;
relation->rel_flags |= REL_deleted;
relation->rel_flags &= ~REL_deleting;
// Release relation triggers
MET_release_triggers(tdbb, &relation->rel_pre_store);
MET_release_triggers(tdbb, &relation->rel_post_store);
MET_release_triggers(tdbb, &relation->rel_pre_erase);
MET_release_triggers(tdbb, &relation->rel_post_erase);
MET_release_triggers(tdbb, &relation->rel_pre_modify);
MET_release_triggers(tdbb, &relation->rel_post_modify);
CMP_release(tdbb, (REQ)request);
break;
}

View File

@ -242,9 +242,10 @@ void trig::compile(tdbb* _tdbb) {
} catch (...) {
_tdbb->tdbb_default = old_pool;
compile_in_progress = FALSE;
if (request)
if (request) {
CMP_release(_tdbb,request);
else
request = NULL;
} else
delete new_pool;
throw;
}
@ -261,10 +262,12 @@ void trig::compile(tdbb* _tdbb) {
}
}
// Not yet implemented.
// Inteded to be used when process is asked to release resources
BOOLEAN trig::release() {
return FALSE;
BOOLEAN trig::release(tdbb* _tdbb) {
if (!blr/*sys_trigger*/ || !request || CMP_clone_active(request))
return FALSE;
CMP_release(_tdbb, request);
request = NULL;
}
extern "C" {

View File

@ -551,7 +551,7 @@ typedef struct trig {
class rel* relation; // Trigger parent relation
class str* name; // Trigger name
void compile(tdbb* _tdbb); // Ensure that trigger is compiled
BOOLEAN release(); // Try to free trigger request
BOOLEAN release(tdbb* _tdbb); // Try to free trigger request
} *TRIG;
typedef Firebird::vector<trig> trig_vec;

View File

@ -35,7 +35,7 @@
* 2002-09-16 Nickolay Samofatov - Deferred trigger compilation changes
*/
/*
$Id: met.epp,v 1.19 2002-09-26 18:13:02 skidder Exp $
$Id: met.epp,v 1.20 2002-09-27 22:59:24 skidder Exp $
*/
// This MUST be at the top of the file
#ifdef DARWIN
@ -177,6 +177,77 @@ static inline void gds__vtov(CONST UCHAR* s1, SCHAR* s2, SSHORT val)
gds__vtov(reinterpret_cast<CONST SCHAR*>(s1), s2, val);
}
// Decompile all triggers from vector
void release_cached_triggers(TDBB tdbb, TRIG_VEC vector)
{
trig_vec::iterator ptr, end;
if (!vector) return;
for (ptr = vector->begin(), end = vector->end(); ptr < end; ptr++)
ptr->release(tdbb);
}
void MET_clear_cache(TDBB tdbb)
{
/**************************************
*
* M E T _ c l e a r _ t r i g g e r _ c a c h e
*
**************************************
*
* Functional description
* Try to release all resources locked by cached triggers
*
**************************************/
DBB dbb;
VEC relations;
REL relation;
vec::iterator ptr, end;
trig_vec::iterator tptr, tend;
SET_TDBB(tdbb);
dbb = tdbb->tdbb_database;
relations = dbb->dbb_relations;
for (ptr = relations->begin(), end = relations->end(); ptr < end; ptr++)
{
relation = REL(*ptr);
if (!relation) continue;
release_cached_triggers(tdbb,relation->rel_pre_store);
release_cached_triggers(tdbb,relation->rel_post_store);
release_cached_triggers(tdbb,relation->rel_pre_erase);
release_cached_triggers(tdbb,relation->rel_post_erase);
release_cached_triggers(tdbb,relation->rel_pre_modify);
release_cached_triggers(tdbb,relation->rel_post_modify);
}
VEC procedures;
PRC procedure;
if ( (procedures = dbb->dbb_procedures) )
do {
procedure = NULL;
for (ptr = procedures->begin(), end = procedures->end();
ptr < end; ptr++)
{
if ( (procedure = PRC(*ptr)) && (procedure->prc_use_count == 0) )
{
CMP_release(tdbb, procedure->prc_request);
procedure->prc_flags &= ~PRC_being_altered;
MET_remove_procedure(tdbb, procedure->prc_id, procedure);
// Begin iteration again because vector contents was modified
// There are ways to do it more efficiently, but such condition
// currently happens very rarely. Only when procedure is created
// and we are trying to drop one of indices it uses w/o server
// restart
break;
}
}
} while (procedure);
}
void MET_activate_shadow( TDBB tdbb)
{
@ -2286,7 +2357,7 @@ void MET_parse_sys_trigger(TDBB tdbb, REL relation)
request->req_flags |= req_ignore_perm;
}
save_trigger_data(tdbb, ptr, relation, request, NULL, NULL, FALSE, 0);
save_trigger_data(tdbb, ptr, relation, request, NULL, NULL, TRUE, 0);
}
}
@ -2854,13 +2925,11 @@ void MET_remove_procedure( TDBB tdbb, int id, PRC procedure)
VEC vector;
SSHORT i;
USHORT save_proc_flags;
BOOLEAN free_procedure_block = TRUE;
SET_TDBB(tdbb);
dbb = tdbb->tdbb_database;
if (!procedure) {
free_procedure_block = FALSE;
/** If we are in here then dfw.e/modify_procedure() called us **/
if (!(vector = dbb->dbb_procedures))
return;
@ -2871,10 +2940,13 @@ void MET_remove_procedure( TDBB tdbb, int id, PRC procedure)
/* Procedure that is being altered may have references
to it by other procedures via pointer to current meta
data structure, so don't loose the structure or the pointer.
data structure, so don't loose the structure or the pointer. */
// Nickolay Samofatov, 28 Sep 2002. Enabled this code. Why was it disabled ?
// Its absence caused coredumps in some cases because its request and other
// data is freed after this call and procedure block is no longer valid
if (!(procedure->prc_flags & PRC_being_altered))
(*vector)[id] = (BLK) NULL_PTR;
*/
/* deallocate all structure which were allocated. The procedure
* blr is originally read into a new pool from which all request

View File

@ -76,6 +76,7 @@ extern BOOLEAN MET_relation_owns_trigger (TDBB, const TEXT *, const TEXT *);
extern BOOLEAN MET_relation_default_class (TDBB, const TEXT *, const TEXT *);
void MET_release_existence(struct rel *);
void MET_release_triggers(TDBB, TRIG_VEC *);
void MET_clear_cache(TDBB);
void MET_remove_procedure(TDBB, int, PRC);
void MET_revoke(TDBB, struct tra *, TEXT *, TEXT *, TEXT *);
TEXT*MET_save_name(TDBB, CONST TEXT*);