8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 09:20:39 +01:00

Make TIP cache initialization atomic. This fixes possible crash due to recursive access to the TIP cache during its initialization, when the shared memory is not yet initialized but dbb_tpc_cache is already created.

This commit is contained in:
Dmitry Yemanov 2024-01-29 18:02:33 +03:00
parent 854d7fb849
commit 987d6ac1e3
2 changed files with 16 additions and 10 deletions

View File

@ -1838,8 +1838,7 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch
// Initialize TIP cache. We do this late to give SDW a chance to
// work while we read states for all interesting transactions
dbb->dbb_tip_cache = FB_NEW_POOL(*dbb->dbb_permanent) TipCache(dbb);
dbb->dbb_tip_cache->initializeTpc(tdbb);
dbb->dbb_tip_cache = TipCache::create(tdbb);
// linger
dbb->dbb_linger_seconds = MET_get_linger(tdbb);
@ -3215,8 +3214,7 @@ JAttachment* JProvider::createDatabase(CheckStatusWrapper* user_status, const ch
config->notify();
// Initialize TIP cache
dbb->dbb_tip_cache = FB_NEW_POOL(*dbb->dbb_permanent) TipCache(dbb);
dbb->dbb_tip_cache->initializeTpc(tdbb);
dbb->dbb_tip_cache = TipCache::create(tdbb);
// Init complete - we can release dbInitMutex
dbb->dbb_flags &= ~(DBB_new | DBB_creating);

View File

@ -57,12 +57,13 @@ public:
explicit TipCache(Database* dbb);
~TipCache();
// Attach to shared memory objects and populate process-local structures.
// If shared memory area did not exist - populate initial TIP by reading cache
// from disk.
// This function has no in-process synchronization, assuming caller prevents
// concurrent use of object being initialized.
void initializeTpc(thread_db *tdbb);
static TipCache* create(thread_db* tdbb)
{
const auto dbb = tdbb->getDatabase();
Firebird::AutoPtr<TipCache> tipCache(FB_NEW_POOL(*dbb->dbb_permanent) TipCache(dbb));
tipCache->initializeTpc(tdbb);
return tipCache.release();
}
// Disconnect from shared memory objects
void finalizeTpc(thread_db* tdbb);
@ -299,6 +300,13 @@ private:
Firebird::SyncObject m_sync_status;
// Attach to shared memory objects and populate process-local structures.
// If shared memory area did not exist - populate initial TIP by reading cache
// from disk.
// This function has no in-process synchronization, assuming caller prevents
// concurrent use of object being initialized.
void initializeTpc(thread_db *tdbb);
void initTransactionsPerBlock(ULONG blockSize);
// Returns block holding transaction state.