| 370 | } |
| 371 | |
| 372 | TipCache::StatusBlockData::StatusBlockData(thread_db* tdbb, TipCache* tipCache, ULONG blockSize, TpcBlockNumber blkNumber) |
| 373 | : blockNumber(blkNumber), |
| 374 | memory(NULL), |
| 375 | existenceLock(tdbb, sizeof(TpcBlockNumber), LCK_tpc_block, this, tpc_block_blocking_ast), |
| 376 | cache(tipCache), |
| 377 | acceptAst(false) |
| 378 | { |
| 379 | Database* dbb = tdbb->getDatabase(); |
| 380 | |
| 381 | existenceLock.setKey(blockNumber); |
| 382 | |
| 383 | if (!LCK_lock(tdbb, &existenceLock, LCK_PR, LCK_WAIT)) |
| 384 | ERR_bugcheck_msg("Unable to obtain memory block lock"); |
| 385 | |
| 386 | PathName fileName = makeSharedMemoryFileName(dbb, blockNumber, false); |
| 387 | |
| 388 | try |
| 389 | { |
| 390 | // Here SharedMemory constructor is called with skipLock parameter set to true. |
| 391 | // Appropriate locking is performed by existenceLock using LM. |
| 392 | // This should be in sync with SharedMemoryBase::unlinkFile() call |
| 393 | // in TipCache::StatusBlockData::clear(). |
| 394 | memory = FB_NEW_POOL(*dbb->dbb_permanent) SharedMemory<TransactionStatusBlock>( |
| 395 | fileName.c_str(), blockSize, |
| 396 | &cache->memBlockInitializer, true); |
| 397 | |
| 398 | const auto* header = memory->getHeader(); |
| 399 | cache->memBlockInitializer.checkHeader(header); |
| 400 | |
| 401 | LCK_convert(tdbb, &existenceLock, LCK_SR, LCK_WAIT); // never fails |
| 402 | acceptAst = true; |
| 403 | } |
| 404 | catch (const Exception& ex) |
| 405 | { |
| 406 | iscLogException("TPC: Cannot initialize the shared memory region (transactions status block)", ex); |
| 407 | LCK_release(tdbb, &existenceLock); |
| 408 | throw; |
| 409 | } |
| 410 | |
| 411 | fb_assert(memory->getHeader()->mhb_version == TPC_VERSION); |
| 412 | } |
| 413 | |
| 414 | PathName TipCache::StatusBlockData::makeSharedMemoryFileName(Database* dbb, TpcBlockNumber n, bool fullPath) |
| 415 | { |
nothing calls this directly
no test coverage detected