aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Scripting/ScriptReloadMgr.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-07-17 17:37:06 +0200
committerShauren <shauren.trinity@gmail.com>2016-07-17 17:37:06 +0200
commita9a13d10f7c510bb392539608cb276435a78b688 (patch)
tree6a2c89377eb8302baa8d98442379abf94bdf01dc /src/server/game/Scripting/ScriptReloadMgr.cpp
parenta5f6a80f0cdbd2ce1db5ca32d24253c81bcbcf5e (diff)
parent201d09ec34edc697553d79eac4bf2f659308f495 (diff)
Merge branch '6.x' of https://github.com/TrinityCore/TrinityCore into legion
Diffstat (limited to 'src/server/game/Scripting/ScriptReloadMgr.cpp')
-rw-r--r--src/server/game/Scripting/ScriptReloadMgr.cpp58
1 files changed, 45 insertions, 13 deletions
diff --git a/src/server/game/Scripting/ScriptReloadMgr.cpp b/src/server/game/Scripting/ScriptReloadMgr.cpp
index d13fa9c30f0..b0c9b6821d2 100644
--- a/src/server/game/Scripting/ScriptReloadMgr.cpp
+++ b/src/server/game/Scripting/ScriptReloadMgr.cpp
@@ -194,6 +194,8 @@ public:
static Optional<std::shared_ptr<ScriptModule>>
CreateFromPath(fs::path const& path, Optional<fs::path> cache_path);
+ static void ScheduleDelayedDelete(ScriptModule* module);
+
char const* GetScriptModuleRevisionHash() const override
{
return _getScriptModuleRevisionHash();
@@ -287,8 +289,13 @@ Optional<std::shared_ptr<ScriptModule>>
GetFunctionFromSharedLibrary(handle, "AddScripts", addScripts) &&
GetFunctionFromSharedLibrary(handle, "GetScriptModule", getScriptModule) &&
GetFunctionFromSharedLibrary(handle, "GetBuildDirective", getBuildDirective))
- return std::make_shared<ScriptModule>(std::move(holder), getScriptModuleRevisionHash,
+ {
+ auto module = new ScriptModule(std::move(holder), getScriptModuleRevisionHash,
addScripts, getScriptModule, getBuildDirective, path);
+
+ // Unload the module at the next update tick as soon as all references are removed
+ return std::shared_ptr<ScriptModule>(module, ScheduleDelayedDelete);
+ }
else
{
TC_LOG_ERROR("scripts.hotswap", "Could not extract all required functions from the shared library \"%s\"!",
@@ -937,13 +944,6 @@ private:
}
}
- sScriptMgr->SetScriptContext(module_name);
- (*module)->AddScripts();
- TC_LOG_TRACE("scripts.hotswap", ">> Registered all scripts of module %s.", module_name.c_str());
-
- if (swap_context)
- sScriptMgr->SwapScriptContext();
-
// Create the source listener
auto listener = Trinity::make_unique<SourceUpdateListener>(
sScriptReloadMgr->GetSourceDirectory() / module_name,
@@ -952,8 +952,16 @@ private:
// Store the module
_known_modules_build_directives.insert(std::make_pair(module_name, (*module)->GetBuildDirective()));
_running_script_modules.insert(std::make_pair(module_name,
- std::make_pair(std::move(*module), std::move(listener))));
+ std::make_pair(*module, std::move(listener))));
_running_script_module_names.insert(std::make_pair(path, module_name));
+
+ // Process the script loading after the module was registered correctly (#17557).
+ sScriptMgr->SetScriptContext(module_name);
+ (*module)->AddScripts();
+ TC_LOG_TRACE("scripts.hotswap", ">> Registered all scripts of module %s.", module_name.c_str());
+
+ if (swap_context)
+ sScriptMgr->SwapScriptContext();
}
void ProcessReloadScriptModule(fs::path const& path)
@@ -1435,6 +1443,26 @@ private:
fs::path temporary_cache_path_;
};
+class ScriptModuleDeleteMessage
+{
+public:
+ explicit ScriptModuleDeleteMessage(ScriptModule* module)
+ : module_(module) { }
+
+ void operator() (HotSwapScriptReloadMgr*)
+ {
+ module_.reset();
+ }
+
+private:
+ std::unique_ptr<ScriptModule> module_;
+};
+
+void ScriptModule::ScheduleDelayedDelete(ScriptModule* module)
+{
+ sScriptReloadMgr->QueueMessage(ScriptModuleDeleteMessage(module));
+}
+
/// Maps efsw actions to strings
static char const* ActionToString(efsw::Action action)
{
@@ -1592,11 +1620,15 @@ void SourceUpdateListener::handleFileAction(efsw::WatchID watchid, std::string c
std::shared_ptr<ModuleReference>
ScriptReloadMgr::AcquireModuleReferenceOfContext(std::string const& context)
{
- auto const itr = sScriptReloadMgr->_running_script_modules.find(context);
- if (itr != sScriptReloadMgr->_running_script_modules.end())
- return itr->second.first;
- else
+ // Return empty references for the static context exported by the worldserver
+ if (context == ScriptMgr::GetNameOfStaticContext())
return { };
+
+ auto const itr = sScriptReloadMgr->_running_script_modules.find(context);
+ ASSERT(itr != sScriptReloadMgr->_running_script_modules.end()
+ && "Requested a reference to a non existent script context!");
+
+ return itr->second.first;
}
// Returns the full hot swap implemented ScriptReloadMgr