8
0
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:
hvlad 2018-03-13 19:44:33 +02:00
parent ab22e4f7a2
commit e5ba540295
7 changed files with 70 additions and 8 deletions

View File

@ -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;
}; };

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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