summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Bindings/Plugin.cpp2
-rw-r--r--src/Bindings/PluginManager.cpp67
-rw-r--r--src/Bindings/PluginManager.h22
-rw-r--r--src/Server.cpp10
4 files changed, 75 insertions, 26 deletions
diff --git a/src/Bindings/Plugin.cpp b/src/Bindings/Plugin.cpp
index de82fbca2..3f1645188 100644
--- a/src/Bindings/Plugin.cpp
+++ b/src/Bindings/Plugin.cpp
@@ -45,7 +45,7 @@ void cPlugin::Unload(void)
AString cPlugin::GetLocalFolder(void) const
{
- return std::string("Plugins/") + m_FolderName;
+ return "Plugins" + cFile::GetPathSeparator() + m_FolderName;
}
diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp
index 6593097dd..310a3968b 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -165,35 +165,54 @@ void cPluginManager::InsertDefaultPlugins(cSettingsRepositoryInterface & a_Setti
void cPluginManager::Tick(float a_Dt)
{
- // Unload plugins that have been scheduled for unloading:
- AStringVector PluginsToUnload;
+ decltype(m_PluginsNeedAction) PluginsNeedAction;
{
- cCSLock Lock(m_CSPluginsToUnload);
- std::swap(m_PluginsToUnload, PluginsToUnload);
+ cCSLock Lock(m_CSPluginsNeedAction);
+ std::swap(m_PluginsNeedAction, PluginsNeedAction);
}
- for (auto & folder: PluginsToUnload)
+
+ // Process deferred actions:
+ for (auto & CurrentPlugin : PluginsNeedAction)
{
- bool HasUnloaded = false;
- bool HasFound = false;
- for (auto & plugin: m_Plugins)
+ auto & Action = CurrentPlugin.first;
+ auto & Folder = CurrentPlugin.second;
+
+ bool WasLoaded = false;
+ bool WasFound = false;
+ for (auto & Plugin: m_Plugins)
{
- if (plugin->GetFolderName() == folder)
+ if (Plugin->GetFolderName() == Folder)
{
- HasFound = true;
- if (plugin->IsLoaded())
+ WasFound = true;
+ if (Plugin->IsLoaded())
{
- plugin->Unload();
- HasUnloaded = true;
+ switch (Action)
+ {
+ case PluginAction::Reload :
+ {
+ // Reload plugins by unloading, then loading:
+ Plugin->Unload();
+ Plugin->Load();
+ break;
+ }
+ case PluginAction::Unload :
+ {
+ // Unload plugins that have been scheduled for unloading:
+ Plugin->Unload();
+ break;
+ }
+ }
+ WasLoaded = true;
}
}
}
- if (!HasFound)
+ if (!WasFound)
{
- LOG("Cannot unload plugin in folder \"%s\", there's no such plugin folder", folder.c_str());
+ LOG("Cannot act on plugin in folder \"%s\", there's no such plugin folder", Folder.c_str());
}
- else if (!HasUnloaded)
+ else if (!WasLoaded)
{
- LOG("Cannot unload plugin in folder \"%s\", it has not been loaded.", folder.c_str());
+ LOG("Cannot act on plugin in folder \"%s\", it has not been loaded.", Folder.c_str());
}
} // for plugin - m_Plugins[]
@@ -1317,8 +1336,18 @@ void cPluginManager::UnloadPluginsNow()
void cPluginManager::UnloadPlugin(const AString & a_PluginFolder)
{
- cCSLock Lock(m_CSPluginsToUnload);
- m_PluginsToUnload.push_back(a_PluginFolder);
+ cCSLock Lock(m_CSPluginsNeedAction);
+ m_PluginsNeedAction.emplace_back(PluginAction::Unload, a_PluginFolder);
+}
+
+
+
+
+
+void cPluginManager::ReloadPlugin(const AString & a_PluginFolder)
+{
+ cCSLock Lock(m_CSPluginsNeedAction);
+ m_PluginsNeedAction.emplace_back(PluginAction::Reload, a_PluginFolder);
}
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index 353950f18..8d75509a1 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -162,6 +162,14 @@ public:
} ; // tolua_export
+ /** Defines the deferred actions needed for a plugin */
+ enum class PluginAction
+ {
+ Reload,
+ Unload
+ };
+
+
/** Used as a callback for enumerating bound commands */
class cCommandEnumCallback
{
@@ -303,6 +311,10 @@ public:
Note that this function returns before the plugin is unloaded, to avoid deadlocks. */
void UnloadPlugin(const AString & a_PluginFolder); // tolua_export
+ /** Queues the specified plugin to be reloaded in the next call to Tick().
+ Note that this function returns before the plugin is unloaded, to avoid deadlocks. */
+ void ReloadPlugin(const AString & a_PluginFolder); // tolua_export
+
/** Loads the plugin from the specified plugin folder.
Returns true if the plugin was loaded successfully or was already loaded before, false otherwise. */
bool LoadPlugin(const AString & a_PluginFolder); // tolua_export
@@ -408,13 +420,13 @@ private:
typedef std::map<AString, cCommandReg> CommandMap;
- /** FolderNames of plugins that should be unloaded.
- The plugins will be unloaded within the next call to Tick(), to avoid multithreading issues.
- Protected against multithreaded access by m_CSPluginsToUnload. */
- AStringVector m_PluginsToUnload;
+ /** FolderNames of plugins that need an action (unload, reload, ...).
+ The plugins will be acted upon within the next call to Tick(), to avoid multithreading issues.
+ Protected against multithreaded access by m_CSPluginsNeedAction. */
+ std::vector<std::pair<PluginAction, AString>> m_PluginsNeedAction;
/** Protects m_PluginsToUnload against multithreaded access. */
- mutable cCriticalSection m_CSPluginsToUnload;
+ mutable cCriticalSection m_CSPluginsNeedAction;
/** All plugins that have been found in the Plugins folder. */
cPluginPtrs m_Plugins;
diff --git a/src/Server.cpp b/src/Server.cpp
index 67629ef2c..2730d3511 100644
--- a/src/Server.cpp
+++ b/src/Server.cpp
@@ -463,7 +463,15 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac
}
else if (split[0] == "reload")
{
- cPluginManager::Get()->ReloadPlugins();
+ if (split.size() > 1)
+ {
+ cPluginManager::Get()->ReloadPlugin(split[1]);
+ a_Output.Out("Plugin reload scheduled");
+ }
+ else
+ {
+ cPluginManager::Get()->ReloadPlugins();
+ }
a_Output.Finished();
return;
}