diff --git a/src/jrd/Attachment.cpp b/src/jrd/Attachment.cpp index c1fd45f57f..fc1f69a2d7 100644 --- a/src/jrd/Attachment.cpp +++ b/src/jrd/Attachment.cpp @@ -217,6 +217,20 @@ Jrd::Attachment::~Attachment() { delete att_trace_manager; + for (Function** iter = att_functions.begin(); iter < att_functions.end(); ++iter) + { + Function* const function = *iter; + if (function) + delete function; + } + + for (jrd_prc** iter = att_procedures.begin(); iter < att_procedures.end(); ++iter) + { + jrd_prc* const procedure = *iter; + if (procedure) + delete procedure; + } + while (att_pools.hasData()) deletePool(att_pools.pop()); diff --git a/src/jrd/ExtEngineManager.cpp b/src/jrd/ExtEngineManager.cpp index 468485d1e5..914132547d 100644 --- a/src/jrd/ExtEngineManager.cpp +++ b/src/jrd/ExtEngineManager.cpp @@ -886,7 +886,7 @@ ExtEngineManager::Trigger::Trigger(thread_db* tdbb, MemoryPool& pool, CompilerSc ExtEngineManager::Trigger::~Trigger() { - // hvlad: shouldn't we call trigger->dispose() here ? + trigger->dispose(); } @@ -1121,22 +1121,23 @@ void ExtEngineManager::initialize() void ExtEngineManager::closeAttachment(thread_db* tdbb, Attachment* attachment) { - Array enginesCopy; + EnginesMap enginesCopy; { // scope ReadLockGuard readGuard(enginesLock, FB_FUNCTION); EnginesMap::Accessor accessor(&engines); for (bool found = accessor.getFirst(); found; found = accessor.getNext()) - enginesCopy.add(accessor.current()->second); + enginesCopy.put(accessor.current()->first, accessor.current()->second); } RefDeb(DEB_RLS_JATT, "ExtEngineManager::closeAttachment"); EngineCheckout cout(tdbb, FB_FUNCTION, true); - for (Array::iterator i = enginesCopy.begin(); i != enginesCopy.end(); ++i) + EnginesMap::Accessor accessor(&enginesCopy); + for (bool found = accessor.getFirst(); found; found = accessor.getNext()) { - IExternalEngine* engine = *i; + IExternalEngine* engine = accessor.current()->second; EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine, true); if (attInfo) @@ -1145,6 +1146,27 @@ void ExtEngineManager::closeAttachment(thread_db* tdbb, Attachment* attachment) ContextManager ctxManager(tdbb, attInfo, attInfo->adminCharSet); FbLocalStatus status; engine->closeAttachment(&status, attInfo->context); //// FIXME: log status + + // Check whether the engine is used by other attachments. + // If no one uses, release it. + bool close = true; + WriteLockGuard writeGuard(enginesLock, FB_FUNCTION); + + EnginesAttachmentsMap::Accessor ea_accessor(&enginesAttachments); + for (bool ea_found = ea_accessor.getFirst(); ea_found; ea_found = ea_accessor.getNext()) + { + if (ea_accessor.current()->first.engine == engine) + { + close = false; // engine is in use, no need to release + break; + } + } + + if (close) + { + if (engines.remove(accessor.current()->first)) // If engine has already been deleted - nothing to do + PluginManagerInterfacePtr()->releasePlugin(engine); + } } delete attInfo; diff --git a/src/jrd/Function.h b/src/jrd/Function.h index 3658a5ceab..47bf646d7d 100644 --- a/src/jrd/Function.h +++ b/src/jrd/Function.h @@ -70,6 +70,16 @@ namespace Jrd virtual bool checkCache(thread_db* tdbb) const; virtual void clearCache(thread_db* tdbb); + virtual ~Function() + { + delete fun_external; + } + + virtual void releaseExternal() + { + delete fun_external; + fun_external = NULL; + } public: int (*fun_entrypoint)(); // function entrypoint USHORT fun_inputs; // input arguments diff --git a/src/jrd/Routine.cpp b/src/jrd/Routine.cpp index 94336c0c55..e13ae6c5e3 100644 --- a/src/jrd/Routine.cpp +++ b/src/jrd/Routine.cpp @@ -367,6 +367,7 @@ void Routine::remove(thread_db* tdbb) setSecurityName(""); setId(0); setDefaultCount(0); + releaseExternal(); } } diff --git a/src/jrd/Routine.h b/src/jrd/Routine.h index 67e07193bb..5ee9ccd82b 100644 --- a/src/jrd/Routine.h +++ b/src/jrd/Routine.h @@ -150,6 +150,7 @@ namespace Jrd void release(thread_db* tdbb); void releaseStatement(thread_db* tdbb); void remove(thread_db* tdbb); + virtual void releaseExternal() {}; public: virtual int getObjectType() const = 0; diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index fd08d8fc60..0a3d13dd07 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -8286,8 +8286,6 @@ void TrigVector::release(thread_db* tdbb) const JrdStatement* stmt = t->statement; if (stmt) stmt->release(tdbb); - - delete t->extTrigger; } delete this; diff --git a/src/jrd/jrd.h b/src/jrd/jrd.h index 9f79fca39e..4b62c5f1d4 100644 --- a/src/jrd/jrd.h +++ b/src/jrd/jrd.h @@ -165,6 +165,11 @@ public: extBody(p), extTrigger(NULL) {} + + virtual ~Trigger() + { + delete extTrigger; + } }; @@ -248,9 +253,20 @@ public: prc_record_format = NULL; } + virtual ~jrd_prc() + { + delete prc_external; + } + virtual bool checkCache(thread_db* tdbb) const; virtual void clearCache(thread_db* tdbb); + virtual void releaseExternal() + { + delete prc_external; + prc_external = NULL; + } + protected: virtual bool reload(thread_db* tdbb); // impl is in met.epp };