summaryrefslogtreecommitdiffstats
path: root/src/Bindings
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Bindings/LuaState.cpp19
-rw-r--r--src/Bindings/LuaState.h7
-rw-r--r--src/Bindings/PluginLua.cpp7
-rw-r--r--src/Bindings/PluginLua.h5
-rw-r--r--src/Bindings/PluginManager.cpp31
-rw-r--r--src/Bindings/PluginManager.h6
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 */