3636#include " ../common/classes/fb_string.h"
3737#include " ../common/classes/init.h"
3838#include " ../common/classes/semaphore.h"
39+ #include " ../common/classes/RefMutex.h"
3940#include " ../common/config/config.h"
4041#include " ../common/config/config_file.h"
4142#include " ../common/utils_proto.h"
@@ -455,7 +456,7 @@ namespace
455456 const PathName& pplugName)
456457 : module (pmodule), regPlugin(preg), pluginLoaderConfig(pconfig),
457458 confName (getPool(), pconfName), plugName(getPool(), pplugName),
458- delay(DEFAULT_DELAY)
459+ processingDelayedDelete( false ), delay(DEFAULT_DELAY)
459460 {
460461 if (pluginLoaderConfig.hasData ())
461462 {
@@ -472,7 +473,7 @@ namespace
472473#ifdef DEBUG_PLUGINS
473474 RegisteredPlugin& r (module ->getPlugin (regPlugin));
474475 fprintf (stderr, " ConfiguredPlugin %s module %s registered as %s type %d order %d\n " ,
475- plugName.c_str (), module ->getName (), r.name , r.type , regPlugin);
476+ plugName.c_str (), module ->getName (), r.name . c_str () , r.type , regPlugin);
476477#endif
477478 }
478479
@@ -516,6 +517,8 @@ namespace
516517 { }
517518
518519 int release ();
520+ static void processDelayedDelete ();
521+
519522 private:
520523 ~ConfiguredPlugin () {}
521524 void destroy ();
@@ -525,6 +528,7 @@ namespace
525528 RefPtr<ConfigFile> pluginLoaderConfig;
526529 PathName confName;
527530 PathName plugName;
531+ bool processingDelayedDelete;
528532
529533 static const FB_UINT64 DEFAULT_DELAY = 1000000 * 60 ; // 1 min
530534 FB_UINT64 delay;
@@ -587,7 +591,7 @@ namespace
587591 ~FactoryParameter ()
588592 {
589593#ifdef DEBUG_PLUGINS
590- fprintf (stderr, " ~FactoryParameter places configuredPlugin %s in unload query for %d seconds\n " ,
594+ fprintf (stderr, " ~FactoryParameter places configuredPlugin %s in unload query for %lld seconds\n " ,
591595 configuredPlugin->getPlugName (), configuredPlugin->getReleaseDelay () / 1000000 );
592596#endif
593597 FbLocalStatus ls;
@@ -696,6 +700,9 @@ namespace
696700#endif
697701 }
698702
703+ typedef HalfStaticArray<ConfiguredPlugin*, 16 > DelayedDelete;
704+ static GlobalPtr<DelayedDelete> delayedDelete;
705+
699706 int ConfiguredPlugin::release ()
700707 {
701708 int x = --refCounter;
@@ -711,6 +718,15 @@ namespace
711718 if (refCounter != 0 )
712719 return 1 ;
713720
721+ if (Why::timerThreadStopped () && !processingDelayedDelete && delayedDelete)
722+ {
723+ // delay delete
724+ addRef ();
725+ delayedDelete->push (this );
726+
727+ return 1 ;
728+ }
729+
714730 destroy ();
715731 }
716732
@@ -723,6 +739,26 @@ namespace
723739 return 1 ;
724740 }
725741
742+ void ConfiguredPlugin::processDelayedDelete ()
743+ {
744+ DelayedDelete& dd (delayedDelete);
745+ MutexEnsureUnlock g (plugins->mutex , FB_FUNCTION);
746+ g.enter ();
747+ for (unsigned n = 0 ; n < dd.getCount (); ++n)
748+ {
749+ ConfiguredPlugin* ptr = dd[n];
750+ if (ptr)
751+ {
752+ g.leave ();
753+ ptr->processingDelayedDelete = true ;
754+ ptr->release ();
755+ g.enter ();
756+ }
757+ dd[n] = nullptr ;
758+ }
759+ delayedDelete->clear ();
760+ }
761+
726762 PluginModule* modules = NULL ;
727763
728764 PluginModule* current = NULL ;
@@ -1213,6 +1249,10 @@ void PluginManager::threadDetach()
12131249 modules->threadDetach ();
12141250}
12151251
1252+ void PluginManager::deleteDelayed ()
1253+ {
1254+ ConfiguredPlugin::processDelayedDelete ();
1255+ }
12161256
12171257} // namespace Firebird
12181258
0 commit comments