8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 04:43:03 +01:00

Fixed leak of ThreadSync instance when module (for. ex. engine) is unloaded before worker threads gone.

This commit is contained in:
hvlad 2018-04-20 23:41:46 +03:00
parent 3735171922
commit 999c757d65
3 changed files with 85 additions and 6 deletions

View File

@ -31,6 +31,7 @@
#include "firebird.h"
#include "fb_tls.h"
#include "init.h"
#include "../ThreadStart.h"
#include "SyncObject.h"
#include "Synchronize.h"
@ -182,6 +183,37 @@ void Synchronize::shutdown()
}
class ThreadSyncInstance : public ThreadSync
{
typedef InstanceControl::InstanceLink<ThreadSyncInstance, InstanceControl::PRIORITY_REGULAR> Link;
public:
ThreadSyncInstance(const char* desc)
: ThreadSync(desc)
{
m_link = FB_NEW Link(this);
}
virtual ~ThreadSyncInstance()
{
if (m_link)
{
m_link->remove();
delete m_link;
}
}
// Used at InstanceControl::dtor
void dtor()
{
m_link = nullptr;
delete this;
}
private:
Link* m_link;
};
/// ThreadSync
TLS_DECLARE(ThreadSync*, threadIndex);
@ -210,7 +242,7 @@ ThreadSync* ThreadSync::getThread(const char* desc)
if (!thread)
{
thread = FB_NEW ThreadSync(desc);
thread = FB_NEW ThreadSyncInstance(desc);
fb_assert(thread == findThread());
}
@ -220,6 +252,12 @@ ThreadSync* ThreadSync::getThread(const char* desc)
void ThreadSync::setThread(ThreadSync* thread)
{
if (thread != NULL)
{
ThreadSync* other = findThread();
fb_assert(other == NULL);
}
TLS_SET(threadIndex, thread);
}

View File

@ -227,12 +227,37 @@ namespace Firebird
{
MutexLockGuard guard(*StaticMutex::mutex, "InstanceControl::InstanceList::InstanceList");
next = instanceList;
prev = nullptr;
if (instanceList)
instanceList->prev = this;
instanceList = this;
}
InstanceControl::InstanceList::~InstanceList()
{
delete next;
fb_assert(next == nullptr);
fb_assert(prev == nullptr);
}
void InstanceControl::InstanceList::remove()
{
MutexLockGuard guard(*StaticMutex::mutex, FB_FUNCTION);
unlist();
}
void InstanceControl::InstanceList::unlist()
{
if (instanceList == this)
instanceList = next;
if (next)
next->prev = this->prev;
if (prev)
prev->next = this->next;
prev = nullptr;
next = nullptr;
}
void InstanceControl::destructors()
@ -299,8 +324,13 @@ namespace Firebird
}
} while (nextPriority != currentPriority);
delete instanceList;
instanceList = 0;
while (instanceList)
{
InstanceList* item = instanceList;
item->unlist();
delete item;
}
}
void InstanceControl::registerGdsCleanup(FPTR_VOID cleanup)

View File

@ -71,10 +71,16 @@ public:
virtual ~InstanceList();
static void destructors();
// remove self from common list under StaticMutex protection
void remove();
private:
InstanceList* next;
DtorPriority priority;
virtual void dtor() = 0;
void unlist();
InstanceList* next;
InstanceList* prev;
DtorPriority priority;
};
template <typename T, InstanceControl::DtorPriority P = InstanceControl::PRIORITY_REGULAR>
@ -90,6 +96,11 @@ public:
fb_assert(link);
}
void remove()
{
InstanceList::remove();
}
void dtor()
{
fb_assert(link);