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

Fixed CORE-4997: Races when 2 threads try to establish first enbedded connections to engine simultaneously

This commit is contained in:
alexpeshkoff 2015-11-09 09:52:24 +00:00
parent 226166bd38
commit d969134c2f

View File

@ -199,11 +199,27 @@ public:
// InitInstance - allocate instance of class T on first request.
template <typename T>
class DefaultInstanceAllocator
{
public:
static T* create()
{
return FB_NEW_POOL(*getDefaultMemoryPool()) T(*getDefaultMemoryPool());
}
static void destroy(T* inst)
{
delete inst;
}
};
template <typename T, class A = DefaultInstanceAllocator<T> >
class InitInstance : private InstanceControl
{
private:
T* instance;
volatile bool flag;
A allocator;
public:
InitInstance()
@ -217,7 +233,7 @@ public:
MutexLockGuard guard(*StaticMutex::mutex, "InitInstance");
if (!flag)
{
instance = FB_NEW_POOL(*getDefaultMemoryPool()) T(*getDefaultMemoryPool());
instance = allocator.create();
flag = true;
// Put ourselves into linked list for cleanup.
// Allocated pointer is saved by InstanceList::constructor.
@ -231,7 +247,7 @@ public:
{
MutexLockGuard guard(*StaticMutex::mutex, "InitInstance - dtor");
flag = false;
delete instance;
A::destroy(instance);
instance = NULL;
}
};
@ -239,31 +255,36 @@ public:
// Static - create instance of some class in static char[] buffer. Never destroy it.
template <typename T>
class Static
class StaticInstanceAllocator
{
private:
char buf[sizeof(T) + FB_ALIGNMENT];
T* t;
public:
Static()
T* create()
{
t = new((void*) FB_ALIGN(buf, FB_ALIGNMENT)) T();
return new((void*) FB_ALIGN(buf, FB_ALIGNMENT)) T();
}
static void destroy(T*)
{ }
};
template <typename T>
class Static : private InitInstance<T, StaticInstanceAllocator<T> >
{
public:
Static()
{ }
T* operator->()
{
return t;
return &(this->operator()());
}
T* operator&()
{
return t;
}
operator T()
{
return *t;
return operator->();
}
};