mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 00:03:02 +01:00
This should fix bug CORE-5702 : Firebird Handle Leak Windows
This commit is contained in:
parent
ab22e4f7a2
commit
e5ba540295
@ -313,7 +313,7 @@ public:
|
|||||||
typedef void VoidNoParam();
|
typedef void VoidNoParam();
|
||||||
|
|
||||||
explicit UnloadDetectorHelper(MemoryPool&)
|
explicit UnloadDetectorHelper(MemoryPool&)
|
||||||
: cleanup(NULL), flagOsUnload(false)
|
: cleanup(NULL), thdDetach(NULL), flagOsUnload(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void registerMe()
|
void registerMe()
|
||||||
@ -348,6 +348,11 @@ public:
|
|||||||
cleanup = function;
|
cleanup = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setThreadDetach(VoidNoParam* function)
|
||||||
|
{
|
||||||
|
thdDetach = function;
|
||||||
|
}
|
||||||
|
|
||||||
void doClean()
|
void doClean()
|
||||||
{
|
{
|
||||||
flagOsUnload = false;
|
flagOsUnload = false;
|
||||||
@ -359,8 +364,15 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void threadDetach()
|
||||||
|
{
|
||||||
|
if (thdDetach)
|
||||||
|
thdDetach();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VoidNoParam* cleanup;
|
VoidNoParam* cleanup;
|
||||||
|
VoidNoParam* thdDetach;
|
||||||
bool flagOsUnload;
|
bool flagOsUnload;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,6 +213,10 @@ interface PluginFactory : Versioned
|
|||||||
interface PluginModule : Versioned
|
interface PluginModule : Versioned
|
||||||
{
|
{
|
||||||
void doClean();
|
void doClean();
|
||||||
|
|
||||||
|
version: // 3.0.3 => 3.0.4
|
||||||
|
// Used to release resources allocated per-thread
|
||||||
|
void threadDetach();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface to deal with plugins here and there, returned by master interface
|
// Interface to deal with plugins here and there, returned by master interface
|
||||||
|
@ -736,6 +736,7 @@ namespace Firebird
|
|||||||
struct VTable : public IVersioned::VTable
|
struct VTable : public IVersioned::VTable
|
||||||
{
|
{
|
||||||
void (CLOOP_CARG *doClean)(IPluginModule* self) throw();
|
void (CLOOP_CARG *doClean)(IPluginModule* self) throw();
|
||||||
|
void (CLOOP_CARG *threadDetach)(IPluginModule* self) throw();
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -749,12 +750,21 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const unsigned VERSION = 2;
|
static const unsigned VERSION = 3;
|
||||||
|
|
||||||
void doClean()
|
void doClean()
|
||||||
{
|
{
|
||||||
static_cast<VTable*>(this->cloopVTable)->doClean(this);
|
static_cast<VTable*>(this->cloopVTable)->doClean(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void threadDetach()
|
||||||
|
{
|
||||||
|
if (cloopVTable->version < 3)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
static_cast<VTable*>(this->cloopVTable)->threadDetach(this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IPluginManager : public IVersioned
|
class IPluginManager : public IVersioned
|
||||||
@ -7004,6 +7014,7 @@ namespace Firebird
|
|||||||
{
|
{
|
||||||
this->version = Base::VERSION;
|
this->version = Base::VERSION;
|
||||||
this->doClean = &Name::cloopdoCleanDispatcher;
|
this->doClean = &Name::cloopdoCleanDispatcher;
|
||||||
|
this->threadDetach = &Name::cloopthreadDetachDispatcher;
|
||||||
}
|
}
|
||||||
} vTable;
|
} vTable;
|
||||||
|
|
||||||
@ -7021,6 +7032,18 @@ namespace Firebird
|
|||||||
StatusType::catchException(0);
|
StatusType::catchException(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CLOOP_CARG cloopthreadDetachDispatcher(IPluginModule* self) throw()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<Name*>(self)->Name::threadDetach();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
StatusType::catchException(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IPluginModule> > >
|
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IPluginModule> > >
|
||||||
@ -7037,6 +7060,7 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void doClean() = 0;
|
virtual void doClean() = 0;
|
||||||
|
virtual void threadDetach() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Name, typename StatusType, typename Base>
|
template <typename Name, typename StatusType, typename Base>
|
||||||
|
@ -426,9 +426,12 @@ static Static<EngineFactory> engineFactory;
|
|||||||
|
|
||||||
void registerEngine(IPluginManager* iPlugin)
|
void registerEngine(IPluginManager* iPlugin)
|
||||||
{
|
{
|
||||||
getUnloadDetector()->setCleanup(shutdownBeforeUnload);
|
UnloadDetectorHelper* module = getUnloadDetector();
|
||||||
|
module->setCleanup(shutdownBeforeUnload);
|
||||||
|
module->setThreadDetach(threadDetach);
|
||||||
|
|
||||||
iPlugin->registerPluginFactory(IPluginManager::TYPE_PROVIDER, CURRENT_ENGINE, &engineFactory);
|
iPlugin->registerPluginFactory(IPluginManager::TYPE_PROVIDER, CURRENT_ENGINE, &engineFactory);
|
||||||
getUnloadDetector()->registerMe();
|
module->registerMe();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Jrd
|
} // namespace Jrd
|
||||||
|
@ -389,6 +389,14 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void threadDetach()
|
||||||
|
{
|
||||||
|
if (cleanup)
|
||||||
|
cleanup->threadDetach();
|
||||||
|
if (next)
|
||||||
|
next->threadDetach();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~PluginModule()
|
~PluginModule()
|
||||||
{
|
{
|
||||||
@ -492,8 +500,6 @@ namespace
|
|||||||
|
|
||||||
IPluginBase* factory(IFirebirdConf *iFirebirdConf);
|
IPluginBase* factory(IFirebirdConf *iFirebirdConf);
|
||||||
|
|
||||||
~ConfiguredPlugin();
|
|
||||||
|
|
||||||
const char* getPlugName()
|
const char* getPlugName()
|
||||||
{
|
{
|
||||||
return plugName.c_str();
|
return plugName.c_str();
|
||||||
@ -519,6 +525,8 @@ namespace
|
|||||||
int release();
|
int release();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
~ConfiguredPlugin();
|
||||||
|
|
||||||
RefPtr<PluginModule> module;
|
RefPtr<PluginModule> module;
|
||||||
unsigned int regPlugin;
|
unsigned int regPlugin;
|
||||||
RefPtr<ConfigFile> pluginLoaderConfig;
|
RefPtr<ConfigFile> pluginLoaderConfig;
|
||||||
@ -682,6 +690,8 @@ namespace
|
|||||||
|
|
||||||
ConfiguredPlugin::~ConfiguredPlugin()
|
ConfiguredPlugin::~ConfiguredPlugin()
|
||||||
{
|
{
|
||||||
|
MutexLockGuard g(plugins->mutex, FB_FUNCTION);
|
||||||
|
|
||||||
if (!destroyingPluginsMap)
|
if (!destroyingPluginsMap)
|
||||||
{
|
{
|
||||||
plugins->remove(MapKey(module->getPlugin(regPlugin).type, plugName));
|
plugins->remove(MapKey(module->getPlugin(regPlugin).type, plugName));
|
||||||
@ -718,8 +728,6 @@ namespace
|
|||||||
|
|
||||||
int ConfiguredPlugin::release()
|
int ConfiguredPlugin::release()
|
||||||
{
|
{
|
||||||
MutexLockGuard g(plugins->mutex, FB_FUNCTION);
|
|
||||||
|
|
||||||
int x = --refCounter;
|
int x = --refCounter;
|
||||||
|
|
||||||
#ifdef DEBUG_PLUGINS
|
#ifdef DEBUG_PLUGINS
|
||||||
@ -1172,6 +1180,13 @@ void PluginManager::waitForType(unsigned int typeThatMustGoAway)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PluginManager::threadDetach()
|
||||||
|
{
|
||||||
|
MutexLockGuard g(plugins->mutex, FB_FUNCTION);
|
||||||
|
modules->threadDetach();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Firebird
|
} // namespace Firebird
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -54,6 +54,7 @@ public:
|
|||||||
|
|
||||||
static void shutdown();
|
static void shutdown();
|
||||||
static void waitForType(unsigned int typeThatMustGoAway);
|
static void waitForType(unsigned int typeThatMustGoAway);
|
||||||
|
static void threadDetach();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Firebird
|
} // namespace Firebird
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
#include "../yvalve/YObjects.h"
|
#include "../yvalve/YObjects.h"
|
||||||
#include "../yvalve/why_proto.h"
|
#include "../yvalve/why_proto.h"
|
||||||
#include "../yvalve/prepa_proto.h"
|
#include "../yvalve/prepa_proto.h"
|
||||||
|
#include "../yvalve/PluginManager.h"
|
||||||
#include "../jrd/constants.h"
|
#include "../jrd/constants.h"
|
||||||
#include "../jrd/build_no.h"
|
#include "../jrd/build_no.h"
|
||||||
#include "../common/classes/ClumpletWriter.h"
|
#include "../common/classes/ClumpletWriter.h"
|
||||||
@ -3172,6 +3173,7 @@ void ThreadCleanup::initThreadCleanup()
|
|||||||
void ThreadCleanup::finiThreadCleanup()
|
void ThreadCleanup::finiThreadCleanup()
|
||||||
{
|
{
|
||||||
pthread_setspecific(key, NULL);
|
pthread_setspecific(key, NULL);
|
||||||
|
PluginManager::threadDetach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3204,6 +3206,7 @@ void ThreadCleanup::initThreadCleanup()
|
|||||||
|
|
||||||
void ThreadCleanup::finiThreadCleanup()
|
void ThreadCleanup::finiThreadCleanup()
|
||||||
{
|
{
|
||||||
|
PluginManager::threadDetach();
|
||||||
}
|
}
|
||||||
#endif // #ifdef WIN_NT
|
#endif // #ifdef WIN_NT
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user