mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 13:23:02 +01:00
Fixed possible server crash + minor refactoring.
This commit is contained in:
parent
73dc69f655
commit
8033131d18
@ -384,6 +384,66 @@ int DatabaseSnapshot::blockingAst(void* ast_object)
|
||||
}
|
||||
|
||||
|
||||
void DatabaseSnapshot::initialize(thread_db* tdbb)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
Database* const dbb = tdbb->getDatabase();
|
||||
fb_assert(dbb);
|
||||
|
||||
if (!dbb->dbb_monitor_lock)
|
||||
{
|
||||
dbb->dbb_monitor_lock = FB_NEW_RPT(*dbb->dbb_permanent, 0)
|
||||
Lock(tdbb, 0, LCK_monitor, dbb, DatabaseSnapshot::blockingAst);
|
||||
LCK_lock(tdbb, dbb->dbb_monitor_lock, LCK_SR, LCK_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DatabaseSnapshot::shutdown(thread_db* tdbb)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
Database* const dbb = tdbb->getDatabase();
|
||||
fb_assert(dbb);
|
||||
|
||||
if (dbb->dbb_monitor_lock)
|
||||
LCK_release(tdbb, dbb->dbb_monitor_lock);
|
||||
}
|
||||
|
||||
|
||||
void DatabaseSnapshot::activate(thread_db* tdbb)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
Database* const dbb = tdbb->getDatabase();
|
||||
fb_assert(dbb);
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
fb_assert(attachment);
|
||||
|
||||
if (dbb->dbb_ast_flags & DBB_monitor_off)
|
||||
{
|
||||
// Enable signal handler for the monitoring stuff
|
||||
|
||||
Attachment::CheckoutSyncGuard monGuard(attachment, dbb->dbb_mon_sync,
|
||||
SYNC_EXCLUSIVE, FB_FUNCTION);
|
||||
|
||||
if (dbb->dbb_ast_flags & DBB_monitor_off)
|
||||
{
|
||||
dbb->dbb_ast_flags &= ~DBB_monitor_off;
|
||||
LCK_lock(tdbb, dbb->dbb_monitor_lock, LCK_SR, LCK_WAIT);
|
||||
|
||||
fb_assert(!(dbb->dbb_ast_flags & DBB_monitor_off));
|
||||
|
||||
// While waiting for return from LCK_lock call above, the blocking AST (see
|
||||
// DatabaseSnapshot::blockingAst) was called and set DBB_monitor_off flag
|
||||
// again. But it do not released lock as lck_id was unknown at that moment.
|
||||
// Do it now to not block another process waiting for a monitoring lock.
|
||||
|
||||
if (dbb->dbb_ast_flags & DBB_monitor_off)
|
||||
LCK_release(tdbb, dbb->dbb_monitor_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
||||
: DataDump(pool), snapshot(pool)
|
||||
{
|
||||
|
@ -337,6 +337,9 @@ public:
|
||||
|
||||
static DatabaseSnapshot* create(thread_db*);
|
||||
static int blockingAst(void*);
|
||||
static void initialize(thread_db*);
|
||||
static void shutdown(thread_db*);
|
||||
static void activate(thread_db*);
|
||||
static bool getRecord(thread_db* tdbb, jrd_rel* relation, FB_UINT64 position, Record* record);
|
||||
|
||||
protected:
|
||||
|
@ -932,10 +932,9 @@ private:
|
||||
static void check_database(thread_db* tdbb, bool async = false);
|
||||
static void commit(thread_db*, jrd_tra*, const bool);
|
||||
static bool drop_files(const jrd_file*);
|
||||
static void enable_monitoring(thread_db* tdbb);
|
||||
static void find_intl_charset(thread_db*, Jrd::Attachment*, const DatabaseOptions*);
|
||||
static jrd_tra* find_transaction(thread_db*);
|
||||
static void init_database_locks(thread_db*);
|
||||
static void init_database_lock(thread_db*);
|
||||
static void run_commit_triggers(thread_db* tdbb, jrd_tra* transaction);
|
||||
static jrd_req* verify_request_synchronization(JrdStatement* statement, USHORT level);
|
||||
static void purge_transactions(thread_db*, Jrd::Attachment*, const bool);
|
||||
@ -1390,11 +1389,11 @@ JAttachment* FB_CARG JProvider::attachDatabase(IStatus* user_status, const char*
|
||||
// Initialize the lock manager
|
||||
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId(), dbb->dbb_config);
|
||||
|
||||
// Initialize locks
|
||||
LCK_init(tdbb, LCK_OWNER_database);
|
||||
LCK_init(tdbb, LCK_OWNER_attachment);
|
||||
init_database_lock(tdbb);
|
||||
|
||||
// Initialize locks
|
||||
init_database_locks(tdbb);
|
||||
jAtt->manualAsyncUnlock(attachment->att_flags);
|
||||
|
||||
INI_init(tdbb);
|
||||
@ -1428,6 +1427,9 @@ JAttachment* FB_CARG JProvider::attachDatabase(IStatus* user_status, const char*
|
||||
dbb->dbb_crypto_manager = FB_NEW(*dbb->dbb_permanent) CryptoManager(tdbb);
|
||||
dbb->dbb_crypto_manager->attach(tdbb, attachment);
|
||||
|
||||
// initialize monitoring
|
||||
DatabaseSnapshot::initialize(tdbb);
|
||||
|
||||
// initialize shadowing as soon as the database is ready for it
|
||||
// but before any real work is done
|
||||
SDW_init(tdbb, options.dpb_activate_shadow, options.dpb_delete_shadow);
|
||||
@ -2555,11 +2557,11 @@ JAttachment* FB_CARG JProvider::createDatabase(IStatus* user_status, const char*
|
||||
// Initialize the lock manager
|
||||
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId(), dbb->dbb_config);
|
||||
|
||||
// Initialize locks
|
||||
LCK_init(tdbb, LCK_OWNER_database);
|
||||
LCK_init(tdbb, LCK_OWNER_attachment);
|
||||
init_database_lock(tdbb);
|
||||
|
||||
// Initialize locks
|
||||
init_database_locks(tdbb);
|
||||
jAtt->manualAsyncUnlock(attachment->att_flags);
|
||||
|
||||
INI_init(tdbb);
|
||||
@ -2598,6 +2600,9 @@ JAttachment* FB_CARG JProvider::createDatabase(IStatus* user_status, const char*
|
||||
|
||||
dbb->dbb_crypto_manager = FB_NEW(*dbb->dbb_permanent) CryptoManager(tdbb);
|
||||
|
||||
// initialize monitoring
|
||||
DatabaseSnapshot::initialize(tdbb);
|
||||
|
||||
if (options.dpb_set_page_buffers)
|
||||
PAG_set_page_buffers(tdbb, options.dpb_page_buffers);
|
||||
|
||||
@ -2637,7 +2642,7 @@ JAttachment* FB_CARG JProvider::createDatabase(IStatus* user_status, const char*
|
||||
|
||||
if (options.dpb_set_db_readonly)
|
||||
{
|
||||
if (!CCH_exclusive (tdbb, LCK_EX, WAIT_PERIOD, &dbbGuard))
|
||||
if (!CCH_exclusive(tdbb, LCK_EX, WAIT_PERIOD, &dbbGuard))
|
||||
{
|
||||
ERR_post(Arg::Gds(isc_lock_timeout) <<
|
||||
Arg::Gds(isc_obj_in_use) << Arg::Str(org_filename));
|
||||
@ -5201,7 +5206,7 @@ bool JRD_reschedule(thread_db* tdbb, SLONG quantum, bool punt)
|
||||
}
|
||||
}
|
||||
|
||||
enable_monitoring(tdbb);
|
||||
DatabaseSnapshot::activate(tdbb);
|
||||
|
||||
tdbb->tdbb_quantum = (tdbb->tdbb_quantum <= 0) ?
|
||||
(quantum ? quantum : QUANTUM) : tdbb->tdbb_quantum;
|
||||
@ -5299,7 +5304,7 @@ static void check_database(thread_db* tdbb, bool async)
|
||||
status_exception::raise(Arg::Gds(isc_cancelled));
|
||||
}
|
||||
|
||||
enable_monitoring(tdbb);
|
||||
DatabaseSnapshot::activate(tdbb);
|
||||
}
|
||||
|
||||
|
||||
@ -5366,36 +5371,6 @@ static bool drop_files(const jrd_file* file)
|
||||
}
|
||||
|
||||
|
||||
static void enable_monitoring(thread_db* tdbb)
|
||||
{
|
||||
Database* const dbb = tdbb->getDatabase();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
// Enable signal handler for the monitoring stuff
|
||||
if (dbb->dbb_ast_flags & DBB_monitor_off)
|
||||
{
|
||||
Attachment::CheckoutSyncGuard monGuard(attachment, dbb->dbb_mon_sync,
|
||||
SYNC_EXCLUSIVE, FB_FUNCTION);
|
||||
|
||||
if (dbb->dbb_ast_flags & DBB_monitor_off)
|
||||
{
|
||||
dbb->dbb_ast_flags &= ~DBB_monitor_off;
|
||||
LCK_lock(tdbb, dbb->dbb_monitor_lock, LCK_SR, LCK_WAIT);
|
||||
|
||||
fb_assert(!(dbb->dbb_ast_flags & DBB_monitor_off));
|
||||
|
||||
// While waiting for return from LCK_lock call above, the blocking AST (see
|
||||
// DatabaseSnapshot::blockingAst) was called and set DBB_monitor_off flag
|
||||
// again. But it do not released lock as lck_id was unknown at that moment.
|
||||
// Do it now to not block another process waiting for a monitoring lock.
|
||||
|
||||
if (dbb->dbb_ast_flags & DBB_monitor_off)
|
||||
LCK_release(tdbb, dbb->dbb_monitor_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static jrd_tra* find_transaction(thread_db* tdbb)
|
||||
{
|
||||
/**************************************
|
||||
@ -6096,16 +6071,16 @@ static JAttachment* create_attachment(const PathName& alias_name,
|
||||
}
|
||||
|
||||
|
||||
static void init_database_locks(thread_db* tdbb)
|
||||
static void init_database_lock(thread_db* tdbb)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* i n i t _ d a t a b a s e _ l o c k s
|
||||
* i n i t _ d a t a b a s e _ l o c k
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Initialize database locks.
|
||||
* Initialize the main database lock.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
@ -6146,14 +6121,6 @@ static void init_database_locks(thread_db* tdbb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lock shared by all dbb owners, used to signal other processes
|
||||
// to dump their monitoring data and synchronize operations
|
||||
|
||||
lock = FB_NEW_RPT(*dbb->dbb_permanent, 0)
|
||||
Lock(tdbb, 0, LCK_monitor, dbb, DatabaseSnapshot::blockingAst);
|
||||
dbb->dbb_monitor_lock = lock;
|
||||
LCK_lock(tdbb, lock, LCK_SR, LCK_WAIT);
|
||||
}
|
||||
|
||||
|
||||
@ -6475,6 +6442,8 @@ bool JRD_shutdown_database(Database* dbb, const unsigned flags)
|
||||
TRA_header_write(tdbb, dbb, 0); // Update transaction info on header page.
|
||||
#endif
|
||||
|
||||
DatabaseSnapshot::shutdown(tdbb);
|
||||
|
||||
VIO_fini(tdbb);
|
||||
|
||||
if (dbb->dbb_crypto_manager)
|
||||
@ -6488,9 +6457,6 @@ bool JRD_shutdown_database(Database* dbb, const unsigned flags)
|
||||
if (dbb->dbb_crypto_manager)
|
||||
dbb->dbb_crypto_manager->shutdown(tdbb);
|
||||
|
||||
if (dbb->dbb_monitor_lock)
|
||||
LCK_release(tdbb, dbb->dbb_monitor_lock);
|
||||
|
||||
if (dbb->dbb_shadow_lock)
|
||||
LCK_release(tdbb, dbb->dbb_shadow_lock);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user