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"
@@ -453,7 +454,7 @@ namespace
453454 const PathName& pplugName)
454455 : module (pmodule), regPlugin(preg), pluginLoaderConfig(pconfig),
455456 confName (getPool(), pconfName), plugName(getPool(), pplugName),
456- delay(DEFAULT_DELAY)
457+ processingDelayedDelete( false ), delay(DEFAULT_DELAY)
457458 {
458459 if (pluginLoaderConfig.hasData ())
459460 {
@@ -470,7 +471,7 @@ namespace
470471#ifdef DEBUG_PLUGINS
471472 RegisteredPlugin& r (module ->getPlugin (regPlugin));
472473 fprintf (stderr, " ConfiguredPlugin %s module %s registered as %s type %d order %d\n " ,
473- plugName.c_str (), module ->getName (), r.name , r.type , regPlugin);
474+ plugName.c_str (), module ->getName (), r.name . c_str () , r.type , regPlugin);
474475#endif
475476 }
476477
@@ -514,6 +515,8 @@ namespace
514515 { }
515516
516517 int release ();
518+ static void processDelayedDelete ();
519+
517520 private:
518521 ~ConfiguredPlugin () {}
519522 void destroy ();
@@ -523,6 +526,7 @@ namespace
523526 RefPtr<ConfigFile> pluginLoaderConfig;
524527 PathName confName;
525528 PathName plugName;
529+ bool processingDelayedDelete;
526530
527531 static const FB_UINT64 DEFAULT_DELAY = 1000000 * 60 ; // 1 min
528532 FB_UINT64 delay;
@@ -585,7 +589,7 @@ namespace
585589 ~FactoryParameter ()
586590 {
587591#ifdef DEBUG_PLUGINS
588- fprintf (stderr, " ~FactoryParameter places configuredPlugin %s in unload query for %d seconds\n " ,
592+ fprintf (stderr, " ~FactoryParameter places configuredPlugin %s in unload query for %lld seconds\n " ,
589593 configuredPlugin->getPlugName (), configuredPlugin->getReleaseDelay () / 1000000 );
590594#endif
591595 FbLocalStatus ls;
@@ -694,6 +698,9 @@ namespace
694698#endif
695699 }
696700
701+ typedef HalfStaticArray<ConfiguredPlugin*, 16 > DelayedDelete;
702+ static GlobalPtr<DelayedDelete> delayedDelete;
703+
697704 int ConfiguredPlugin::release ()
698705 {
699706 int x = --refCounter;
@@ -709,6 +716,15 @@ namespace
709716 if (refCounter != 0 )
710717 return 1 ;
711718
719+ if (Why::timerThreadStopped () && !processingDelayedDelete && delayedDelete)
720+ {
721+ // delay delete
722+ addRef ();
723+ delayedDelete->push (this );
724+
725+ return 1 ;
726+ }
727+
712728 destroy ();
713729 }
714730
@@ -721,6 +737,26 @@ namespace
721737 return 1 ;
722738 }
723739
740+ void ConfiguredPlugin::processDelayedDelete ()
741+ {
742+ DelayedDelete& dd (delayedDelete);
743+ MutexEnsureUnlock g (plugins->mutex , FB_FUNCTION);
744+ g.enter ();
745+ for (unsigned n = 0 ; n < dd.getCount (); ++n)
746+ {
747+ ConfiguredPlugin* ptr = dd[n];
748+ if (ptr)
749+ {
750+ g.leave ();
751+ ptr->processingDelayedDelete = true ;
752+ ptr->release ();
753+ g.enter ();
754+ }
755+ dd[n] = nullptr ;
756+ }
757+ delayedDelete->clear ();
758+ }
759+
724760 PluginModule* modules = NULL ;
725761
726762 PluginModule* current = NULL ;
@@ -1211,6 +1247,10 @@ void PluginManager::threadDetach()
12111247 modules->threadDetach ();
12121248}
12131249
1250+ void PluginManager::deleteDelayed ()
1251+ {
1252+ ConfiguredPlugin::processDelayedDelete ();
1253+ }
12141254
12151255} // namespace Firebird
12161256
0 commit comments