MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / releaseSharedMemory

Method releaseSharedMemory

src/jrd/tpc.cpp:774–838  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

772
773
774void TipCache::releaseSharedMemory(thread_db* tdbb, TraNumber oldest_old, TraNumber oldest_new)
775{
776 Database* dbb = tdbb->getDatabase();
777
778 TpcBlockNumber lastInterestingBlockNumber = oldest_new / m_transactionsPerBlock;
779
780 // If we didn't cross block boundary - there is nothing to do.
781 // Note that due to the fuzziness of our caller's memory access to variables
782 // there is an unlikely possibility that we might lose one such event.
783 // This is not too bad, and next such event will clean things up.
784 if (oldest_old / m_transactionsPerBlock == lastInterestingBlockNumber)
785 return;
786
787 // Populate array of blocks that might be unmapped and deleted.
788 // We scan for blocks to clean up in descending order, but delete them in
789 // ascending order to ensure for robust operation.
790 PathName fileName;
791 HalfStaticArray<TpcBlockNumber, 16> blocksToCleanup;
792
793 for (TpcBlockNumber cleanupCounter = lastInterestingBlockNumber - SAFETY_GAP_BLOCKS;
794 cleanupCounter; cleanupCounter--)
795 {
796 TpcBlockNumber blockNumber = cleanupCounter - 1;
797 PathName fileName = StatusBlockData::makeSharedMemoryFileName(dbb, blockNumber, true);
798
799 struct stat st;
800 // If file is not found -- look no further
801 if (stat(fileName.c_str(), &st) != 0)
802 break;
803
804 blocksToCleanup.add(blockNumber);
805 }
806
807 if (blocksToCleanup.isEmpty())
808 return;
809
810 SyncLockGuard sync(&m_sync_status, SYNC_EXCLUSIVE, FB_FUNCTION);
811 while (blocksToCleanup.hasData())
812 {
813 TpcBlockNumber blockNumber = blocksToCleanup.pop();
814
815 if (m_blocks_memory.locate(blockNumber))
816 {
817 StatusBlockData* block = m_blocks_memory.current();
818 m_blocks_memory.fastRemove();
819 delete block;
820 }
821
822 // Signal other processes to release resources
823 Lock temp(tdbb, sizeof(TpcBlockNumber), LCK_tpc_block);
824 temp.setKey(blockNumber);
825 if (!LCK_lock(tdbb, &temp, LCK_EX, LCK_WAIT))
826 {
827 gds__log("TPC BUG: Unable to obtain cleanup lock for block %" UQUADFORMAT, blockNumber);
828 fb_assert(false);
829 break;
830 }
831

Callers

nothing calls this directly

Calls 14

LCK_lockFunction · 0.85
LCK_releaseFunction · 0.85
getDatabaseMethod · 0.80
statClass · 0.70
unlinkFunction · 0.50
c_strMethod · 0.45
addMethod · 0.45
isEmptyMethod · 0.45
hasDataMethod · 0.45
popMethod · 0.45
locateMethod · 0.45
currentMethod · 0.45

Tested by

no test coverage detected