mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 16:03:02 +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.
|
* 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"
|
#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;
|
relation->rel_index_locks = index;
|
||||||
index->idl_relation = relation;
|
index->idl_relation = relation;
|
||||||
index->idl_id = id;
|
index->idl_id = id;
|
||||||
|
index->idl_count = 0;
|
||||||
|
|
||||||
index->idl_lock = lock = FB_NEW_RPT(*dbb->dbb_permanent, 0) lck;
|
index->idl_lock = lock = FB_NEW_RPT(*dbb->dbb_permanent, 0) lck;
|
||||||
lock->lck_parent = dbb->dbb_lock;
|
lock->lck_parent = dbb->dbb_lock;
|
||||||
|
@ -2290,6 +2290,9 @@ static bool delete_index(TDBB tdbb, SSHORT phase, DFW work, TRA transaction)
|
|||||||
if (index)
|
if (index)
|
||||||
{
|
{
|
||||||
wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
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 ||
|
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, wait))
|
||||||
{
|
{
|
||||||
@ -2775,6 +2778,15 @@ static bool delete_relation(TDBB tdbb, SSHORT phase, DFW work, TRA transaction)
|
|||||||
relation->rel_name = NULL;
|
relation->rel_name = NULL;
|
||||||
relation->rel_flags |= REL_deleted;
|
relation->rel_flags |= REL_deleted;
|
||||||
relation->rel_flags &= ~REL_deleting;
|
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);
|
CMP_release(tdbb, (REQ)request);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -242,9 +242,10 @@ void trig::compile(tdbb* _tdbb) {
|
|||||||
} catch (...) {
|
} catch (...) {
|
||||||
_tdbb->tdbb_default = old_pool;
|
_tdbb->tdbb_default = old_pool;
|
||||||
compile_in_progress = FALSE;
|
compile_in_progress = FALSE;
|
||||||
if (request)
|
if (request) {
|
||||||
CMP_release(_tdbb,request);
|
CMP_release(_tdbb,request);
|
||||||
else
|
request = NULL;
|
||||||
|
} else
|
||||||
delete new_pool;
|
delete new_pool;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -261,10 +262,12 @@ void trig::compile(tdbb* _tdbb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not yet implemented.
|
BOOLEAN trig::release(tdbb* _tdbb) {
|
||||||
// Inteded to be used when process is asked to release resources
|
if (!blr/*sys_trigger*/ || !request || CMP_clone_active(request))
|
||||||
BOOLEAN trig::release() {
|
return FALSE;
|
||||||
return FALSE;
|
|
||||||
|
CMP_release(_tdbb, request);
|
||||||
|
request = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -551,7 +551,7 @@ typedef struct trig {
|
|||||||
class rel* relation; // Trigger parent relation
|
class rel* relation; // Trigger parent relation
|
||||||
class str* name; // Trigger name
|
class str* name; // Trigger name
|
||||||
void compile(tdbb* _tdbb); // Ensure that trigger is compiled
|
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;
|
} *TRIG;
|
||||||
|
|
||||||
typedef Firebird::vector<trig> trig_vec;
|
typedef Firebird::vector<trig> trig_vec;
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
* 2002-09-16 Nickolay Samofatov - Deferred trigger compilation changes
|
* 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
|
// This MUST be at the top of the file
|
||||||
#ifdef DARWIN
|
#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);
|
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)
|
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;
|
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;
|
VEC vector;
|
||||||
SSHORT i;
|
SSHORT i;
|
||||||
USHORT save_proc_flags;
|
USHORT save_proc_flags;
|
||||||
BOOLEAN free_procedure_block = TRUE;
|
|
||||||
|
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
dbb = tdbb->tdbb_database;
|
dbb = tdbb->tdbb_database;
|
||||||
|
|
||||||
if (!procedure) {
|
if (!procedure) {
|
||||||
free_procedure_block = FALSE;
|
|
||||||
/** If we are in here then dfw.e/modify_procedure() called us **/
|
/** If we are in here then dfw.e/modify_procedure() called us **/
|
||||||
if (!(vector = dbb->dbb_procedures))
|
if (!(vector = dbb->dbb_procedures))
|
||||||
return;
|
return;
|
||||||
@ -2871,10 +2940,13 @@ void MET_remove_procedure( TDBB tdbb, int id, PRC procedure)
|
|||||||
|
|
||||||
/* Procedure that is being altered may have references
|
/* Procedure that is being altered may have references
|
||||||
to it by other procedures via pointer to current meta
|
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))
|
if (!(procedure->prc_flags & PRC_being_altered))
|
||||||
(*vector)[id] = (BLK) NULL_PTR;
|
(*vector)[id] = (BLK) NULL_PTR;
|
||||||
*/
|
|
||||||
|
|
||||||
/* deallocate all structure which were allocated. The procedure
|
/* deallocate all structure which were allocated. The procedure
|
||||||
* blr is originally read into a new pool from which all request
|
* 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 *);
|
extern BOOLEAN MET_relation_default_class (TDBB, const TEXT *, const TEXT *);
|
||||||
void MET_release_existence(struct rel *);
|
void MET_release_existence(struct rel *);
|
||||||
void MET_release_triggers(TDBB, TRIG_VEC *);
|
void MET_release_triggers(TDBB, TRIG_VEC *);
|
||||||
|
void MET_clear_cache(TDBB);
|
||||||
void MET_remove_procedure(TDBB, int, PRC);
|
void MET_remove_procedure(TDBB, int, PRC);
|
||||||
void MET_revoke(TDBB, struct tra *, TEXT *, TEXT *, TEXT *);
|
void MET_revoke(TDBB, struct tra *, TEXT *, TEXT *, TEXT *);
|
||||||
TEXT*MET_save_name(TDBB, CONST TEXT*);
|
TEXT*MET_save_name(TDBB, CONST TEXT*);
|
||||||
|
Loading…
Reference in New Issue
Block a user