diff options
Diffstat (limited to '')
-rw-r--r-- | src/Bindings/LuaState.cpp | 19 | ||||
-rw-r--r-- | src/Bindings/LuaState.h | 7 | ||||
-rw-r--r-- | src/Bindings/PluginLua.cpp | 7 | ||||
-rw-r--r-- | src/Bindings/PluginLua.h | 5 | ||||
-rw-r--r-- | src/Bindings/PluginManager.cpp | 31 | ||||
-rw-r--r-- | src/Bindings/PluginManager.h | 6 |
6 files changed, 68 insertions, 7 deletions
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 2acf7df84..ec63d2767 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -19,6 +19,7 @@ extern "C" #include "LuaJson.h" #include "../Entities/Entity.h" #include "../BlockEntities/BlockEntity.h" +#include "../DeadlockDetect.h" @@ -2225,6 +2226,24 @@ void cLuaState::LogApiCallParamFailure(const char * a_FnName, const char * a_Par +void cLuaState::TrackInDeadlockDetect(cDeadlockDetect & a_DeadlockDetect) +{ + a_DeadlockDetect.TrackCriticalSection(m_CS, Printf("cLuaState %s", m_SubsystemName.c_str())); +} + + + + + +void cLuaState::UntrackInDeadlockDetect(cDeadlockDetect & a_DeadlockDetect) +{ + a_DeadlockDetect.UntrackCriticalSection(m_CS); +} + + + + + int cLuaState::ReportFnCallErrors(lua_State * a_LuaState) { LOGWARNING("LUA: %s", lua_tostring(a_LuaState, -1)); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 558e8d79a..1a56c18ff 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -46,6 +46,7 @@ class cLuaServerHandle; class cLuaTCPLink; class cLuaUDPEndpoint; class cPluginLua; +class cDeadlockDetect; @@ -822,6 +823,12 @@ public: logs the stack trace and stack values. */ void LogApiCallParamFailure(const char * a_FnName, const char * a_ParamNames); + /** Adds this object's CS to the DeadlockDetect's tracked CSs. */ + void TrackInDeadlockDetect(cDeadlockDetect & a_DeadlockDetect); + + /** Removes this object's CS from the DeadlockDetect's tracked CSs. */ + void UntrackInDeadlockDetect(cDeadlockDetect & a_DeadlockDetect); + protected: cCriticalSection m_CS; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index f2896abde..202477962 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -33,10 +33,12 @@ extern "C" //////////////////////////////////////////////////////////////////////////////// // cPluginLua: -cPluginLua::cPluginLua(const AString & a_PluginDirectory) : +cPluginLua::cPluginLua(const AString & a_PluginDirectory, cDeadlockDetect & a_DeadlockDetect) : cPlugin(a_PluginDirectory), - m_LuaState(Printf("plugin %s", a_PluginDirectory.c_str())) + m_LuaState(Printf("plugin %s", a_PluginDirectory.c_str())), + m_DeadlockDetect(a_DeadlockDetect) { + m_LuaState.TrackInDeadlockDetect(a_DeadlockDetect); } @@ -46,6 +48,7 @@ cPluginLua::cPluginLua(const AString & a_PluginDirectory) : cPluginLua::~cPluginLua() { Close(); + m_LuaState.UntrackInDeadlockDetect(m_DeadlockDetect); } diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index dc3c91880..703cb8ead 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -62,7 +62,7 @@ public: - cPluginLua(const AString & a_PluginDirectory); + cPluginLua(const AString & a_PluginDirectory, cDeadlockDetect & a_DeadlockDetect); ~cPluginLua(); virtual void OnDisable(void) override; @@ -179,6 +179,9 @@ protected: /** Hooks that the plugin has registered. */ cHookMap m_HookMap; + /** The DeadlockDetect object to which the plugin's CS is tracked. */ + cDeadlockDetect & m_DeadlockDetect; + /** Releases all Lua references, notifies and removes all m_Resettables[] and closes the m_LuaState. */ void Close(void); diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 19d2e8b4d..e190abe15 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -32,8 +32,9 @@ cPluginManager * cPluginManager::Get(void) -cPluginManager::cPluginManager(void) : - m_bReloadPlugins(false) +cPluginManager::cPluginManager(cDeadlockDetect & a_DeadlockDetect) : + m_bReloadPlugins(false), + m_DeadlockDetect(a_DeadlockDetect) { } @@ -98,7 +99,7 @@ void cPluginManager::RefreshPluginList(void) } // for plugin - m_Plugins[] if (!hasFound) { - m_Plugins.push_back(std::make_shared<cPluginLua>(folder)); + m_Plugins.push_back(std::make_shared<cPluginLua>(folder, m_DeadlockDetect)); } } // for folder - Folders[] } @@ -601,6 +602,30 @@ bool cPluginManager::CallHookEntityChangedWorld(cEntity & a_Entity, cWorld & a_W bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result) { + // Output the command being executed to log (for troubleshooting deadlocks-in-commands): + if (a_Player != nullptr) + { + auto world = a_Player->GetWorld(); + AString worldName; + Int64 worldAge; + if (world != nullptr) + { + worldName = world->GetName(); + worldAge = world->GetWorldAge(); + } + else + { + worldName = "<no world>"; + worldAge = 0; + } + LOG("Player %s is executing command \"%s\" in world \"%s\" at world age %lld.", + a_Player->GetName().c_str(), + a_EntireCommand.c_str(), + worldName.c_str(), + worldAge + ); + } + FIND_HOOK(HOOK_EXECUTE_COMMAND); VERIFY_HOOK; diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 0423d6af1..7c818ca2d 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -26,6 +26,7 @@ class cPlugin; class cProjectileEntity; class cWorld; class cSettingsRepositoryInterface; +class cDeadlockDetect; struct TakeDamageInfo; typedef SharedPtr<cPlugin> cPluginPtr; @@ -413,8 +414,11 @@ private: /** If set to true, all the plugins will be reloaded within the next call to Tick(). */ bool m_bReloadPlugins; + /** The deadlock detect in which all plugins should track their CSs. */ + cDeadlockDetect & m_DeadlockDetect; - cPluginManager(); + + cPluginManager(cDeadlockDetect & a_DeadlockDetect); virtual ~cPluginManager(); /** Reloads all plugins, defaulting to settings.ini for settings location */ |