From: <ale...@us...> - 2013-02-27 14:49:22
|
Revision: 57706 http://sourceforge.net/p/firebird/code/57706 Author: alexpeshkoff Date: 2013-02-27 14:49:14 +0000 (Wed, 27 Feb 2013) Log Message: ----------- Fixed CORE-3908: Engine leaks memory and crashes when lot of autonomous transactions have been started and finished Modified Paths: -------------- firebird/trunk/src/jrd/tra.cpp firebird/trunk/src/jrd/tra.h Modified: firebird/trunk/src/jrd/tra.cpp =================================================================== --- firebird/trunk/src/jrd/tra.cpp 2013-02-27 02:30:28 UTC (rev 57705) +++ firebird/trunk/src/jrd/tra.cpp 2013-02-27 14:49:14 UTC (rev 57706) @@ -1484,7 +1484,7 @@ // To handle the problems of relation locks, allocate a temporary // transaction block first, seize relation locks, then go ahead and // make up the real transaction block. - MemoryPool* const pool = outer ? outer->tra_pool : attachment->createPool(); + MemoryPool* const pool = outer ? outer->getAutonomousPool() : attachment->createPool(); Jrd::ContextPoolHolder context(tdbb, pool); jrd_tra* const temp = jrd_tra::create(pool, attachment, outer); @@ -1539,7 +1539,7 @@ // To handle the problems of relation locks, allocate a temporary // transaction block first, seize relation locks, then go ahead and // make up the real transaction block. - MemoryPool* const pool = outer ? outer->tra_pool : attachment->createPool(); + MemoryPool* const pool = outer ? outer->getAutonomousPool() : attachment->createPool(); Jrd::ContextPoolHolder context(tdbb, pool); jrd_tra* const temp = jrd_tra::create(pool, attachment, outer); @@ -3271,6 +3271,11 @@ tra_interface->setHandle(NULL); tra_interface->release(); } + + if (tra_autonomous_pool) + { + MemoryPool::deletePool(tra_autonomous_pool); + } } @@ -3304,6 +3309,36 @@ } +MemoryPool* jrd_tra::getAutonomousPool() +{ + if (!tra_autonomous_pool) + { + MemoryPool* pool = tra_pool; + jrd_tra* outer = tra_outer; + while (outer) + { + pool = outer->tra_pool; + outer = outer->tra_outer; + } + tra_autonomous_pool = MemoryPool::createPool(pool, tra_memory_stats); + tra_autonomous_cnt = 0; + } + + return tra_autonomous_pool; +} + + +void jrd_tra::releaseAutonomousPool(MemoryPool* toRelease) +{ + fb_assert(tra_autonomous_pool == toRelease); + if (++tra_autonomous_cnt > TRA_AUTONOMOUS_PER_POOL) + { + MemoryPool::deletePool(tra_autonomous_pool); + tra_autonomous_pool = NULL; + } +} + + /// class TraceSweepEvent TraceSweepEvent::TraceSweepEvent(thread_db* tdbb) Modified: firebird/trunk/src/jrd/tra.h =================================================================== --- firebird/trunk/src/jrd/tra.h 2013-02-27 02:30:28 UTC (rev 57705) +++ firebird/trunk/src/jrd/tra.h 2013-02-27 14:49:14 UTC (rev 57706) @@ -172,11 +172,12 @@ tra_blob_space(NULL), tra_undo_space(NULL), tra_undo_record(NULL), - tra_user_management(NULL) + tra_user_management(NULL), + tra_autonomous_pool(NULL), + tra_autonomous_cnt(0) { if (outer) { - fb_assert(p == outer->tra_pool); tra_arrays = outer->tra_arrays; tra_blobs = outer->tra_blobs; } @@ -203,8 +204,15 @@ { if (transaction) { - if (!attachment || transaction->tra_outer) + if (!attachment) delete transaction; + else if (transaction->tra_outer) + { + jrd_tra* outer = transaction->tra_outer; + MemoryPool* const pool = transaction->tra_pool; + delete transaction; + outer->releaseAutonomousPool(pool); + } else { MemoryPool* const pool = transaction->tra_pool; @@ -282,8 +290,14 @@ Record* tra_undo_record; // temporary record used for the undo purposes UserManagement* tra_user_management; + MemoryPool* tra_autonomous_pool; + USHORT tra_autonomous_cnt; + static const USHORT TRA_AUTONOMOUS_PER_POOL = 64; public: + MemoryPool* getAutonomousPool(); + void releaseAutonomousPool(MemoryPool* toRelease); + SSHORT getLockWait() const { return -tra_lock_timeout; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |