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:
parent
bb6521ee61
commit
0518ca14a3
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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" {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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*);
|
||||
|
Loading…
Reference in New Issue
Block a user