Skip to content

Commit

Permalink
Backported fix for CORE-3908: Engine leaks memory and crashes when lo…
Browse files Browse the repository at this point in the history
…t of autonomous transactions have been started and finished
  • Loading branch information
AlexPeshkoff committed Feb 27, 2013
1 parent 2d04ead commit 2a29d5f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
39 changes: 37 additions & 2 deletions src/jrd/tra.cpp
Expand Up @@ -1604,7 +1604,7 @@ jrd_tra* TRA_start(thread_db* tdbb, ULONG flags, SSHORT lock_timeout, Jrd::jrd_t
// 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 : dbb->createPool();
MemoryPool* const pool = outer ? outer->getAutonomousPool() : dbb->createPool();
Jrd::ContextPoolHolder context(tdbb, pool);
jrd_tra* const temp = jrd_tra::create(pool, attachment, outer);

Expand Down Expand Up @@ -1659,7 +1659,7 @@ jrd_tra* TRA_start(thread_db* tdbb, int tpb_length, const UCHAR* tpb, Jrd::jrd_t
// 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 : dbb->createPool();
MemoryPool* const pool = outer ? outer->getAutonomousPool() : dbb->createPool();
Jrd::ContextPoolHolder context(tdbb, pool);
jrd_tra* const temp = jrd_tra::create(pool, attachment, outer);

Expand Down Expand Up @@ -3541,6 +3541,11 @@ jrd_tra::~jrd_tra()
}

DFW_delete_deferred(this, -1);

if (tra_autonomous_pool)
{
MemoryPool::deletePool(tra_autonomous_pool);
}
}


Expand All @@ -3554,6 +3559,36 @@ UserManagement* jrd_tra::getUserManagement()
}


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) :
Expand Down
14 changes: 12 additions & 2 deletions src/jrd/tra.h
Expand Up @@ -129,11 +129,12 @@ class jrd_tra : public pool_alloc<type_tra>
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;
}
Expand Down Expand Up @@ -162,7 +163,10 @@ class jrd_tra : public pool_alloc<type_tra>
{
if (transaction->tra_outer)
{
jrd_tra* outer = transaction->tra_outer;
MemoryPool* const pool = transaction->tra_pool;
delete transaction;
outer->releaseAutonomousPool(pool);
}
else
{
Expand Down Expand Up @@ -223,8 +227,14 @@ class jrd_tra : public pool_alloc<type_tra>

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;
Expand Down

0 comments on commit 2a29d5f

Please sign in to comment.