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

Backported fix for CORE-1963: Possible server crash on commit when granting/revoking privileges from multiple connections simultaneously.

This commit is contained in:
dimitr 2008-12-11 07:29:11 +00:00
parent 611f4c27ad
commit fc480dfeba
5 changed files with 53 additions and 35 deletions

View File

@ -434,7 +434,7 @@ void DFW_merge_work(jrd_tra* transaction,
}
void DFW_perform_system_work(void)
void DFW_perform_system_work(thread_db* tdbb)
{
/**************************************
*
@ -447,7 +447,12 @@ void DFW_perform_system_work(void)
* system transaction.
*
**************************************/
Database* dbb = GET_DBB();
SET_TDBB(tdbb);
Database* const dbb = tdbb->getDatabase();
THREAD_EXIT();
Firebird::MutexLockGuard guard(dbb->dbb_mutexes[DBB_MUTX_sys_dfw]);
THREAD_ENTER();
DFW_perform_work(dbb->dbb_sys_trans);
}
@ -626,8 +631,30 @@ void DFW_perform_post_commit_work(jrd_tra* transaction)
}
DeferredWork* DFW_post_work(jrd_tra* transaction, enum dfw_t type, const dsc* desc,
USHORT id)
DeferredWork* DFW_post_system_work(thread_db* tdbb, enum dfw_t type, const dsc* desc, USHORT id)
{
/**************************************
*
* D F W _ p o s t _ s y s t e m _ w o r k
*
**************************************
*
* Functional description
* Post work to be deferred to commit time.
*
**************************************/
SET_TDBB(tdbb);
Database* const dbb = tdbb->getDatabase();
THREAD_EXIT();
Firebird::MutexLockGuard guard(dbb->dbb_mutexes[DBB_MUTX_sys_dfw]);
THREAD_ENTER();
return DFW_post_work(dbb->dbb_sys_trans, type, desc, id);
}
DeferredWork* DFW_post_work(jrd_tra* transaction, enum dfw_t type, const dsc* desc, USHORT id)
{
/**************************************
*

View File

@ -27,9 +27,10 @@
USHORT DFW_assign_index_type(Jrd::DeferredWork*, SSHORT, SSHORT);
void DFW_delete_deferred(Jrd::jrd_tra*, SLONG);
void DFW_merge_work(Jrd::jrd_tra*, SLONG, SLONG);
void DFW_perform_system_work(void);
void DFW_perform_system_work(Jrd::thread_db*);
void DFW_perform_work(Jrd::jrd_tra*);
void DFW_perform_post_commit_work(Jrd::jrd_tra*);
Jrd::DeferredWork* DFW_post_system_work(Jrd::thread_db*, enum Jrd::dfw_t, const dsc*, USHORT);
Jrd::DeferredWork* DFW_post_work(Jrd::jrd_tra*, enum Jrd::dfw_t, const dsc*, USHORT);
Jrd::DeferredWork* DFW_post_work_arg(Jrd::jrd_tra*, Jrd::DeferredWork*, const dsc*, USHORT);
void DFW_update_index(const TEXT*, USHORT, const Jrd::SelectivityList&);

View File

@ -192,7 +192,7 @@ bool GRANT_privileges( thread_db* tdbb, SSHORT phase, DeferredWork* work,
break;
}
DFW_perform_system_work();
DFW_perform_system_work(tdbb);
return false;
}
@ -258,7 +258,7 @@ static void define_default_class(
desc.dsc_ttype() = ttype_metadata;
desc.dsc_address = (UCHAR *) relation_name;
desc.dsc_length = strlen(relation_name);
DFW_post_work(dbb->dbb_sys_trans, dfw_scan_relation, &desc, 0);
DFW_post_system_work(tdbb, dfw_scan_relation, &desc, 0);
}
@ -611,7 +611,7 @@ static void purge_default_class( TEXT* object_name, SSHORT obj_type)
desc.dsc_ttype() = ttype_metadata;
desc.dsc_address = (UCHAR *) object_name;
desc.dsc_length = strlen(object_name);
DFW_post_work(dbb->dbb_sys_trans, dfw_scan_relation, &desc, 0);
DFW_post_system_work(tdbb, dfw_scan_relation, &desc, 0);
}
#endif // NOT_USED_OR_REPLACED
@ -796,7 +796,7 @@ static SecurityClass::flags_t save_field_privileges(thread_db* tdbb,
desc.dsc_ttype() = ttype_metadata;
desc.dsc_address = (UCHAR *) relation_name;
desc.dsc_length = strlen(relation_name);
DFW_post_work(dbb->dbb_sys_trans, dfw_update_format, &desc, 0);
DFW_post_system_work(tdbb, dfw_update_format, &desc, 0);
}
return aggregate_public;

View File

@ -420,7 +420,7 @@ void INI_format(const TEXT* owner, const TEXT* charset)
store_functions(tdbb, dbb);
DFW_perform_system_work();
DFW_perform_system_work(tdbb);
add_relation_fields(0);
@ -821,7 +821,7 @@ void INI_update_database()
dbb->dbb_minor_version = header->hdr_ods_minor;
CCH_RELEASE(tdbb, &window);
DFW_perform_system_work();
DFW_perform_system_work(tdbb);
}
#ifdef NOT_USED_OR_REPLACED
@ -888,7 +888,7 @@ static void add_global_fields( USHORT minor_version)
CMP_release(tdbb, handle);
}
DFW_perform_system_work();
DFW_perform_system_work(tdbb);
}
@ -1081,7 +1081,7 @@ static void add_relation_fields( USHORT minor_version)
INTL_ASSIGN_DSC(&desc, CS_METADATA, COLLATE_NONE);
desc.dsc_address = (UCHAR*) names[relfld[RFLD_R_NAME]];
desc.dsc_length = strlen((char*)desc.dsc_address);
DFW_post_work(dbb->dbb_sys_trans, dfw_update_format, &desc, 0);
DFW_post_system_work(tdbb, dfw_update_format, &desc, 0);
}
}
}
@ -1093,7 +1093,7 @@ static void add_relation_fields( USHORT minor_version)
CMP_release(tdbb, m_handle);
}
DFW_perform_system_work();
DFW_perform_system_work(tdbb);
}
@ -1336,15 +1336,13 @@ static void store_generator(thread_db* tdbb, const gen* generator, jrd_req** han
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
jrd_tra* trans = dbb->dbb_sys_trans;
STORE(REQUEST_HANDLE * handle) X IN RDB$GENERATORS
PAD(generator->gen_name, X.RDB$GENERATOR_NAME);
X.RDB$GENERATOR_ID = generator->gen_id;
X.RDB$SYSTEM_FLAG = RDB_system;
if (generator->gen_description)
{
blb* blob = BLB_create(tdbb, trans, &X.RDB$DESCRIPTION);
blb* blob = BLB_create(tdbb, dbb->dbb_sys_trans, &X.RDB$DESCRIPTION);
BLB_put_segment(tdbb,
blob,
reinterpret_cast<const UCHAR*>(generator->gen_description),
@ -1377,8 +1375,6 @@ static void store_global_field(thread_db* tdbb, const gfld* gfield, jrd_req** ha
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
jrd_tra* trans = dbb->dbb_sys_trans;
STORE(REQUEST_HANDLE * handle) X IN RDB$FIELDS
PAD(names[(USHORT)gfield->gfld_name], X.RDB$FIELD_NAME);
X.RDB$FIELD_LENGTH = gfield->gfld_length;
@ -1390,7 +1386,7 @@ static void store_global_field(thread_db* tdbb, const gfld* gfield, jrd_req** ha
X.RDB$SEGMENT_LENGTH.NULL = TRUE;
if (gfield->gfld_dflt_blr)
{
blb* blob = BLB_create(tdbb, trans, &X.RDB$DEFAULT_VALUE);
blb* blob = BLB_create(tdbb, dbb->dbb_sys_trans, &X.RDB$DEFAULT_VALUE);
BLB_put_segment(tdbb,
blob,
gfield->gfld_dflt_blr,
@ -1543,8 +1539,6 @@ static void store_intlnames(thread_db* tdbb, Database* dbb)
CMP_release(tdbb, handle);
handle = NULL;
jrd_tra* trans = dbb->dbb_sys_trans;
for (const COLL_TYPE* collptr = coll_types; collptr->init_collation_name; collptr++)
{
STORE(REQUEST_HANDLE handle) X IN RDB$COLLATIONS USING
@ -1565,7 +1559,7 @@ static void store_intlnames(thread_db* tdbb, Database* dbb)
if (collptr->init_collation_specific_attributes)
{
blb* blob = BLB_create(tdbb, trans, &X.RDB$SPECIFIC_ATTRIBUTES);
blb* blob = BLB_create(tdbb, dbb->dbb_sys_trans, &X.RDB$SPECIFIC_ATTRIBUTES);
BLB_put_segment(tdbb,
blob,
reinterpret_cast<const UCHAR*>(collptr->init_collation_specific_attributes),
@ -1735,15 +1729,13 @@ static void store_trigger(thread_db* tdbb, const jrd_trg* trigger, jrd_req** han
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
jrd_tra* trans = dbb->dbb_sys_trans;
/* indicate that the relation format needs revising */
dsc desc;
desc.dsc_dtype = dtype_text;
INTL_ASSIGN_DSC(&desc, CS_METADATA, COLLATE_NONE);
desc.dsc_address = (UCHAR*) names[trigger->trg_relation];
desc.dsc_length = strlen((char*)desc.dsc_address);
DFW_post_work(trans, dfw_update_format, &desc, 0);
DFW_post_system_work(tdbb, dfw_update_format, &desc, 0);
/* store the trigger */
@ -1754,7 +1746,7 @@ static void store_trigger(thread_db* tdbb, const jrd_trg* trigger, jrd_req** han
X.RDB$SYSTEM_FLAG = RDB_system;
X.RDB$TRIGGER_TYPE = trigger->trg_type;
X.RDB$FLAGS = trigger->trg_flags;
blb* blob = BLB_create(tdbb, trans, &X.RDB$TRIGGER_BLR);
blb* blob = BLB_create(tdbb, dbb->dbb_sys_trans, &X.RDB$TRIGGER_BLR);
BLB_put_segment(tdbb,
blob,
trigger->trg_blr,

View File

@ -442,14 +442,12 @@ const int DBB_max_count = 8;
// Database mutexes
//
const int DBB_MUTX_init_fini = 0; // During startup and shutdown
//const int DBB_MUTX_statistics = 1; // Memory size and counts
//const int DBB_MUTX_replay = 2; // Replay logging
const int DBB_MUTX_dyn = 3; // Dynamic ddl
//const int DBB_MUTX_cache = 4; // Process-private cache management
const int DBB_MUTX_clone = 5; // Request cloning
const int DBB_MUTX_cmp_clone = 6; // Compiled request cloning
const int DBB_MUTX_flush_count = 7; // flush count/time
const int DBB_MUTX_max = 8;
const int DBB_MUTX_dyn = 1; // Dynamic ddl
const int DBB_MUTX_clone = 2; // Request cloning
const int DBB_MUTX_cmp_clone = 3; // Compiled request cloning
const int DBB_MUTX_flush_count = 4; // flush count/time
const int DBB_MUTX_sys_dfw = 5; // system deferred work
const int DBB_MUTX_max = 6;
//
// Flags to indicate normal internal requests vs. dyn internal requests