Skip to content

Commit 987d6ac

Browse files
committed
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.
1 parent 854d7fb commit 987d6ac

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

src/jrd/jrd.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,8 +1838,7 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch
18381838

18391839
// Initialize TIP cache. We do this late to give SDW a chance to
18401840
// work while we read states for all interesting transactions
1841-
dbb->dbb_tip_cache = FB_NEW_POOL(*dbb->dbb_permanent) TipCache(dbb);
1842-
dbb->dbb_tip_cache->initializeTpc(tdbb);
1841+
dbb->dbb_tip_cache = TipCache::create(tdbb);
18431842

18441843
// linger
18451844
dbb->dbb_linger_seconds = MET_get_linger(tdbb);
@@ -3215,8 +3214,7 @@ JAttachment* JProvider::createDatabase(CheckStatusWrapper* user_status, const ch
32153214
config->notify();
32163215

32173216
// Initialize TIP cache
3218-
dbb->dbb_tip_cache = FB_NEW_POOL(*dbb->dbb_permanent) TipCache(dbb);
3219-
dbb->dbb_tip_cache->initializeTpc(tdbb);
3217+
dbb->dbb_tip_cache = TipCache::create(tdbb);
32203218

32213219
// Init complete - we can release dbInitMutex
32223220
dbb->dbb_flags &= ~(DBB_new | DBB_creating);

src/jrd/tpc_proto.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,13 @@ class TipCache
5757
explicit TipCache(Database* dbb);
5858
~TipCache();
5959

60-
// Attach to shared memory objects and populate process-local structures.
61-
// If shared memory area did not exist - populate initial TIP by reading cache
62-
// from disk.
63-
// This function has no in-process synchronization, assuming caller prevents
64-
// concurrent use of object being initialized.
65-
void initializeTpc(thread_db *tdbb);
60+
static TipCache* create(thread_db* tdbb)
61+
{
62+
const auto dbb = tdbb->getDatabase();
63+
Firebird::AutoPtr<TipCache> tipCache(FB_NEW_POOL(*dbb->dbb_permanent) TipCache(dbb));
64+
tipCache->initializeTpc(tdbb);
65+
return tipCache.release();
66+
}
6667

6768
// Disconnect from shared memory objects
6869
void finalizeTpc(thread_db* tdbb);
@@ -299,6 +300,13 @@ class TipCache
299300

300301
Firebird::SyncObject m_sync_status;
301302

303+
// Attach to shared memory objects and populate process-local structures.
304+
// If shared memory area did not exist - populate initial TIP by reading cache
305+
// from disk.
306+
// This function has no in-process synchronization, assuming caller prevents
307+
// concurrent use of object being initialized.
308+
void initializeTpc(thread_db *tdbb);
309+
302310
void initTransactionsPerBlock(ULONG blockSize);
303311

304312
// Returns block holding transaction state.

0 commit comments

Comments
 (0)