Skip to content

Commit 07030d3

Browse files
committed
Frontported fix for bug CORE-6477 : Rare race condition in Plugin Manager could lead to the server crash
1 parent b6b6897 commit 07030d3

1 file changed

Lines changed: 37 additions & 3 deletions

File tree

src/yvalve/PluginManager.cpp

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,10 @@ namespace
500500
void handler()
501501
{ }
502502

503+
int release();
503504
private:
504-
~ConfiguredPlugin();
505+
~ConfiguredPlugin() {}
506+
void destroy();
505507

506508
RefPtr<PluginModule> module;
507509
unsigned int regPlugin;
@@ -653,10 +655,15 @@ namespace
653655

654656
GlobalPtr<PluginsMap> plugins;
655657

656-
ConfiguredPlugin::~ConfiguredPlugin()
658+
void ConfiguredPlugin::destroy()
657659
{
658-
MutexLockGuard g(plugins->mutex, FB_FUNCTION);
660+
// plugins->mutex must be entered by current thread
659661

662+
#ifdef DEV_BUILD
663+
if (!plugins->mutex.tryEnter(FB_FUNCTION))
664+
fb_assert(false);
665+
plugins->mutex.leave();
666+
#endif
660667
if (!destroyingPluginsMap)
661668
{
662669
plugins->remove(MapKey(module->getPlugin(regPlugin).type, plugName));
@@ -676,6 +683,33 @@ namespace
676683
#endif
677684
}
678685

686+
int ConfiguredPlugin::release()
687+
{
688+
int x = --refCounter;
689+
690+
#ifdef DEBUG_PLUGINS
691+
fprintf(stderr, "ConfiguredPlugin::release %s %d\n", plugName.c_str(), x);
692+
#endif
693+
694+
if (x == 0)
695+
{
696+
{ // plugins->mutex scope
697+
MutexLockGuard g(plugins->mutex, FB_FUNCTION);
698+
if (refCounter != 0)
699+
return 1;
700+
701+
destroy();
702+
}
703+
704+
// Must run out of mutex scope to avoid deadlock with PluginManager::threadDetach()
705+
// called when module is unloaded by dtor
706+
delete this;
707+
return 0;
708+
}
709+
710+
return 1;
711+
}
712+
679713
PluginModule* modules = NULL;
680714

681715
PluginModule* current = NULL;

0 commit comments

Comments
 (0)