summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS5
-rw-r--r--Server/Plugins/APIDump/Classes/Plugins.lua11
-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
6 files changed, 89 insertions, 28 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index cf9841ff4..2eb5b05bb 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -37,10 +37,10 @@ lkolbly
LogicParrot
Luksor
M10360
-maxluchterhand1
marmot21
Masy98
mathiascode
+maxluchterhand1
MaxwellScroggs
mborland
mBornand
@@ -53,6 +53,7 @@ nesco
NiLSPACE (formerly STR_Warrior)
p-mcgowan
pokechu22
+pwnOrbitals
rs2k
SamJBarney
Schwertspize
@@ -64,8 +65,8 @@ structinf (xdot)
sweetgiorni
Sxw1212
Taugeshtu
-tigerw (Tiger Wang)
theophriene
+tigerw (Tiger Wang)
tonibm19
TooAngel
UltraCoderRU
diff --git a/Server/Plugins/APIDump/Classes/Plugins.lua b/Server/Plugins/APIDump/Classes/Plugins.lua
index 63f4172e6..adc6bf0b3 100644
--- a/Server/Plugins/APIDump/Classes/Plugins.lua
+++ b/Server/Plugins/APIDump/Classes/Plugins.lua
@@ -675,6 +675,17 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
},
Notes = "Queues the specified plugin to be unloaded. To avoid deadlocks, the unloading happens in the main tick thread asynchronously.",
},
+ ReloadPlugin =
+ {
+ Params =
+ {
+ {
+ Name = "PluginName",
+ Type = "string",
+ },
+ },
+ Notes = "Queues the specified plugin to be reloaded. To avoid deadlocks, the reloading happens in the main tick thread asynchronously.",
+ }
},
Constants =
{
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;
}