3737#include " ../common/classes/fb_string.h"
3838#include " ../common/classes/init.h"
3939#include " ../common/classes/semaphore.h"
40+ #include " ../common/classes/RefMutex.h"
4041#include " ../common/config/config.h"
4142#include " ../common/config/config_file.h"
4243#include " ../common/utils_proto.h"
@@ -476,7 +477,7 @@ namespace
476477 const PathName& pplugName)
477478 : module (pmodule), regPlugin(preg), pluginLoaderConfig(pconfig),
478479 confName (getPool(), pconfName), plugName(getPool(), pplugName),
479- delay(DEFAULT_DELAY)
480+ processingDelayedDelete( false ), delay(DEFAULT_DELAY)
480481 {
481482 if (pluginLoaderConfig.hasData ())
482483 {
@@ -493,7 +494,7 @@ namespace
493494#ifdef DEBUG_PLUGINS
494495 RegisteredPlugin& r (module ->getPlugin (regPlugin));
495496 fprintf (stderr, " ConfiguredPlugin %s module %s registered as %s type %d order %d\n " ,
496- plugName.c_str (), module ->getName (), r.name , r.type , regPlugin);
497+ plugName.c_str (), module ->getName (), r.name . c_str () , r.type , regPlugin);
497498#endif
498499 }
499500
@@ -537,6 +538,7 @@ namespace
537538 { }
538539
539540 int release ();
541+ static void processDelayedDelete ();
540542
541543 private:
542544 ~ConfiguredPlugin () {}
@@ -547,6 +549,7 @@ namespace
547549 RefPtr<ConfigFile> pluginLoaderConfig;
548550 PathName confName;
549551 PathName plugName;
552+ bool processingDelayedDelete;
550553
551554 static const FB_UINT64 DEFAULT_DELAY = 1000000 * 60 ; // 1 min
552555 FB_UINT64 delay;
@@ -620,7 +623,7 @@ namespace
620623 ~FactoryParameter ()
621624 {
622625#ifdef DEBUG_PLUGINS
623- fprintf (stderr, " ~FactoryParameter places configuredPlugin %s in unload query for %d seconds\n " ,
626+ fprintf (stderr, " ~FactoryParameter places configuredPlugin %s in unload query for %lld seconds\n " ,
624627 configuredPlugin->getPlugName (), configuredPlugin->getReleaseDelay () / 1000000 );
625628#endif
626629 LocalStatus ls;
@@ -746,6 +749,9 @@ namespace
746749 *prev = this ;
747750 }
748751
752+ typedef HalfStaticArray<ConfiguredPlugin*, 16 > DelayedDelete;
753+ static GlobalPtr<DelayedDelete> delayedDelete;
754+
749755 int ConfiguredPlugin::release ()
750756 {
751757 int x = --refCounter;
@@ -761,6 +767,15 @@ namespace
761767 if (refCounter != 0 )
762768 return 1 ;
763769
770+ if (Why::timerThreadStopped () && !processingDelayedDelete && delayedDelete)
771+ {
772+ // delay delete
773+ addRef ();
774+ delayedDelete->push (this );
775+
776+ return 1 ;
777+ }
778+
764779 destroy ();
765780 }
766781
@@ -773,6 +788,26 @@ namespace
773788 return 1 ;
774789 }
775790
791+ void ConfiguredPlugin::processDelayedDelete ()
792+ {
793+ DelayedDelete& dd (delayedDelete);
794+ MutexEnsureUnlock g (plugins->mutex , FB_FUNCTION);
795+ g.enter ();
796+ for (unsigned n = 0 ; n < dd.getCount (); ++n)
797+ {
798+ ConfiguredPlugin* ptr = dd[n];
799+ if (ptr)
800+ {
801+ g.leave ();
802+ ptr->processingDelayedDelete = true ;
803+ ptr->release ();
804+ g.enter ();
805+ }
806+ dd[n] = NULL ;
807+ }
808+ delayedDelete->clear ();
809+ }
810+
776811 struct PluginLoadInfo
777812 {
778813 PathName curModule, regName, plugConfigFile;
@@ -1252,6 +1287,10 @@ void PluginManager::threadDetach()
12521287 modules->threadDetach ();
12531288}
12541289
1290+ void PluginManager::deleteDelayed ()
1291+ {
1292+ ConfiguredPlugin::processDelayedDelete ();
1293+ }
12551294
12561295} // namespace Firebird
12571296
0 commit comments