From e4944fa99f3616b1bb8295da035679fb498118c0 Mon Sep 17 00:00:00 2001 From: spx Date: Sun, 30 Jan 2011 15:39:14 +0000 Subject: [PATCH] MeasureScript: Fixed memory leak when DynamicVariables=1. --- Library/MeasureScript.cpp | 171 +++++++++++++++++++++---------------- Library/MeasureScript.h | 23 ++--- Library/lua/LuaManager.cpp | 15 +++- Library/lua/LuaManager.h | 2 +- 4 files changed, 122 insertions(+), 89 deletions(-) diff --git a/Library/MeasureScript.cpp b/Library/MeasureScript.cpp index f043f523..5e5fcb29 100644 --- a/Library/MeasureScript.cpp +++ b/Library/MeasureScript.cpp @@ -21,14 +21,29 @@ CMeasureScript::CMeasureScript(CMeterWindow* meterWindow) : CMeasure(meterWindow CMeasureScript::~CMeasureScript() { - delete m_pLuaScript; + DeleteLuaScript(); + LuaManager::CleanUp(); +} + +void CMeasureScript::DeleteLuaScript() +{ + if (m_pLuaScript) + { + delete m_pLuaScript; + m_pLuaScript = NULL; + } + + m_bUpdateDefined = false; + m_bGetValueDefined = false; + m_bGetStringValueDefined = false; + m_bInitializeDefined = false; } void CMeasureScript::Initialize() { CMeasure::Initialize(); - if( m_bInitializeDefined && m_pLuaScript->IsInitialized() ) + if (m_bInitializeDefined && m_pLuaScript && m_pLuaScript->IsInitialized()) { m_pLuaScript->RunFunction(g_strInitFunction); } @@ -36,13 +51,12 @@ void CMeasureScript::Initialize() bool CMeasureScript::Update() { - if (!CMeasure::PreUpdate()) { return false; } - if( m_bUpdateDefined && m_pLuaScript->IsInitialized() ) + if (m_bUpdateDefined && m_pLuaScript && m_pLuaScript->IsInitialized()) { m_pLuaScript->RunFunction(g_strUpdateFunction); } @@ -52,14 +66,12 @@ bool CMeasureScript::Update() double CMeasureScript::GetValue() { - - if( m_bGetValueDefined && m_pLuaScript->IsInitialized() ) + if (m_bGetValueDefined && m_pLuaScript && m_pLuaScript->IsInitialized()) { return m_pLuaScript->RunFunctionDouble(g_strGetValueFunction); } return CMeasure::GetValue(); - } void CMeasureScript::SetValue(double d) @@ -80,10 +92,9 @@ void CMeasureScript::SetValue(double d) */ const WCHAR* CMeasureScript::GetStringValue(AUTOSCALE autoScale, double scale, int decimals, bool percentual) { - - if (m_bGetStringValueDefined && m_pLuaScript->IsInitialized() ) + if (m_bGetStringValueDefined && m_pLuaScript && m_pLuaScript->IsInitialized()) { - m_strValue = m_pLuaScript->RunFunctionString(g_strGetStringValueFunction) ; + m_strValue = m_pLuaScript->RunFunctionString(g_strGetStringValueFunction); return CheckSubstitute(m_strValue.c_str()); } @@ -113,14 +124,14 @@ static void stackDump(lua_State *L) break; default: - LuaManager::LuaLog(LOG_DEBUG, "%d: %s", i, lua_typename(L, t)); break; + LuaManager::LuaLog(LOG_DEBUG, "%d: %s", i, lua_typename(L, t)); + break; } i--; } LuaManager::LuaLog(LOG_DEBUG, "--------------- Stack Dump Finished ---------------" ); } - /* ** ReadConfig ** @@ -129,95 +140,111 @@ static void stackDump(lua_State *L) */ void CMeasureScript::ReadConfig(CConfigParser& parser, const WCHAR* section) { + // Store the current values + std::string oldScriptFile = m_ScriptFile; + std::string oldTableName = m_TableName; + + // Read common configs CMeasure::ReadConfig(parser, section); - std::string strScriptFile = ConvertToAscii(parser.ReadString(section, L"ScriptFile", L"").c_str()); - std::string strTableName = ConvertToAscii(parser.ReadString(section, L"TableName", L"").c_str()); + m_ScriptFile = ConvertToAscii(parser.ReadString(section, L"ScriptFile", L"").c_str()); + m_TableName = ConvertToAscii(parser.ReadString(section, L"TableName", L"").c_str()); - if (strScriptFile.empty() == false) + if (!m_ScriptFile.empty()) { - if (strTableName.empty() == false) + if (!m_TableName.empty()) { - lua_State* L = LuaManager::GetState(); - - m_pLuaScript = new LuaScript(LuaManager::GetState(), strScriptFile.c_str(), strTableName.c_str()); - - if (m_pLuaScript->IsInitialized()) + if (!m_Initialized || + oldScriptFile != m_ScriptFile || + oldTableName != m_TableName) { - m_bUpdateDefined = m_pLuaScript->FunctionExists(g_strUpdateFunction); - m_bInitializeDefined = m_pLuaScript->FunctionExists(g_strInitFunction); - m_bGetValueDefined = m_pLuaScript->FunctionExists(g_strGetValueFunction); - m_bGetStringValueDefined = m_pLuaScript->FunctionExists(g_strGetStringValueFunction); + lua_State* L = LuaManager::GetState(); - m_pLuaScript->PushTable(); + DeleteLuaScript(); + m_pLuaScript = new LuaScript(LuaManager::GetState(), m_ScriptFile.c_str(), m_TableName.c_str()); - // Push the variable name we want to put a value in. - lua_pushstring(L, "SELF"); - // Push the value - tolua_pushusertype(L, this, "CMeasure"); - // Bind the variable - lua_settable(L, -3); - - // Push the variable name we want to put a value in. - lua_pushstring(L, "SKIN"); - // Push the value - tolua_pushusertype(L, m_MeterWindow, "CMeterWindow"); - // Bind the variable - lua_settable(L, -3); - - // Push the variable name we want to put a value in. - lua_pushstring(L, "RAINMETER"); - // Push the value - tolua_pushusertype(L, m_MeterWindow->GetMainObject(), "CRainmeter"); - // Bind the variable - lua_settable(L, -3); - - // Look i nthe properties table for values to read from the section. - lua_getfield(L, -1, "PROPERTIES"); - if (lua_isnil(L, -1) == 0) + if (m_pLuaScript->IsInitialized()) { - lua_pushnil(L); + m_bUpdateDefined = m_pLuaScript->FunctionExists(g_strUpdateFunction); + m_bInitializeDefined = m_pLuaScript->FunctionExists(g_strInitFunction); + m_bGetValueDefined = m_pLuaScript->FunctionExists(g_strGetValueFunction); + m_bGetStringValueDefined = m_pLuaScript->FunctionExists(g_strGetStringValueFunction); - while(lua_next(L, -2)) + m_pLuaScript->PushTable(); + + // Push the variable name we want to put a value in. + lua_pushstring(L, "SELF"); + // Push the value + tolua_pushusertype(L, this, "CMeasure"); + // Bind the variable + lua_settable(L, -3); + + // Push the variable name we want to put a value in. + lua_pushstring(L, "SKIN"); + // Push the value + tolua_pushusertype(L, m_MeterWindow, "CMeterWindow"); + // Bind the variable + lua_settable(L, -3); + + // Push the variable name we want to put a value in. + lua_pushstring(L, "RAINMETER"); + // Push the value + tolua_pushusertype(L, m_MeterWindow->GetMainObject(), "CRainmeter"); + // Bind the variable + lua_settable(L, -3); + + // Look i nthe properties table for values to read from the section. + lua_getfield(L, -1, "PROPERTIES"); + if (lua_isnil(L, -1) == 0) { - lua_pop(L, 1); + lua_pushnil(L); - const char* strKey = lua_tostring(L, -1); - - std::wstring wstrKey = ConvertToWide(strKey); - std::wstring wstrValue = parser.ReadString(section, wstrKey.c_str(), L"").c_str(); - - if (!wstrValue.empty()) + while(lua_next(L, -2)) { - const wchar_t* wstrValue2 = wstrValue.c_str(); - std::string strStrVal = ConvertToAscii(wstrValue2); - const char* strValue = strStrVal.c_str(); + lua_pop(L, 1); + + const char* strKey = lua_tostring(L, -1); + + std::wstring wstrKey = ConvertToWide(strKey); + std::wstring wstrValue = parser.ReadString(section, wstrKey.c_str(), L""); - lua_pushstring(L,strValue); - lua_settable(L, -3); + if (!wstrValue.empty()) + { + std::string strStrVal = ConvertToAscii(wstrValue.c_str()); + const char* strValue = strStrVal.c_str(); + + lua_pushstring(L, strValue); + lua_settable(L, -3); - lua_pushstring(L,strKey); + lua_pushstring(L, strKey); + } } - } - } - // Pop PROPERTIES table - lua_pop(L, 1); + // Pop PROPERTIES table + lua_pop(L, 1); - // Pop the table - lua_pop(L, 1); + // Pop the table + lua_pop(L, 1); + } + else + { + DeleteLuaScript(); + } } } else { LuaManager::LuaLog(LOG_ERROR, "Script: TableName missing in %s.", m_ANSIName.c_str()); + DeleteLuaScript(); } } else { LuaManager::LuaLog(LOG_ERROR, "Script: ScriptFile missing in %s.", m_ANSIName.c_str()); + DeleteLuaScript(); } } + void CMeasureScript::RunFunctionWithMeter(const char* p_strFunction, CMeter* p_pMeter) { // Get the Lua State @@ -247,7 +274,7 @@ void CMeasureScript::RunFunctionWithMeter(const char* p_strFunction, CMeter* p_p void CMeasureScript::MeterMouseEvent(CMeter* p_pMeter, MOUSE p_eMouse) { - if (m_pLuaScript->IsInitialized()) + if (m_pLuaScript && m_pLuaScript->IsInitialized()) { switch (p_eMouse) { diff --git a/Library/MeasureScript.h b/Library/MeasureScript.h index 5a47a588..f1d7befe 100644 --- a/Library/MeasureScript.h +++ b/Library/MeasureScript.h @@ -7,39 +7,35 @@ class CMeasureScript : public CMeasure { - public: - CMeasureScript(CMeterWindow* meterWindow); virtual ~CMeasureScript(); - void ReadConfig(CConfigParser& parser, const WCHAR* section); - - void Initialize(); - - bool Update(); + virtual void ReadConfig(CConfigParser& parser, const WCHAR* section); + virtual void Initialize(); + virtual bool Update(); + virtual const WCHAR* GetStringValue(AUTOSCALE autoScale, double scale, int decimals, bool percentual); double GetValue(); - void SetValue(double d); - virtual const WCHAR* GetStringValue(AUTOSCALE autoScale, double scale, int decimals, bool percentual); + void DeleteLuaScript(); void MeterMouseEvent(CMeter* p_pMeter, MOUSE p_eMouse); void RunFunctionWithMeter(const char* p_strFunction, CMeter* p_pMeter); - protected: - LuaScript* m_pLuaScript; bool m_bUpdateDefined; bool m_bGetValueDefined; - bool m_bGetStringValueDefined; + bool m_bGetStringValueDefined; bool m_bInitializeDefined; std::wstring m_strValue; - std::wstring m_ScriptTableName; + + std::string m_ScriptFile; + std::string m_TableName; /* Sqrat::Table* m_ScriptTable; @@ -49,7 +45,6 @@ protected: Sqrat::Function* m_InitFunc; Sqrat::Function* m_UpdateTransitionFunc; */ - }; #endif \ No newline at end of file diff --git a/Library/lua/LuaManager.cpp b/Library/lua/LuaManager.cpp index 8ff5b151..727c68d6 100644 --- a/Library/lua/LuaManager.cpp +++ b/Library/lua/LuaManager.cpp @@ -12,7 +12,7 @@ #include "lua_rainmeter_ext.h" -bool LuaManager::m_bInitialized = false; +int LuaManager::m_RefCount = 0; lua_State* LuaManager::m_pState = 0; void LuaManager::Init() @@ -35,11 +35,22 @@ void LuaManager::Init() luaopen_rainmeter_ext(m_pState); } + + ++m_RefCount; } void LuaManager::CleanUp() { - lua_close(m_pState); + if (m_RefCount > 0) + { + --m_RefCount; + } + + if (m_RefCount == 0 && m_pState != 0) + { + lua_close(m_pState); + m_pState = 0; + } } void LuaManager::ReportErrors(lua_State * L) diff --git a/Library/lua/LuaManager.h b/Library/lua/LuaManager.h index 9441a057..b7282d98 100644 --- a/Library/lua/LuaManager.h +++ b/Library/lua/LuaManager.h @@ -20,7 +20,7 @@ public: protected: - static bool m_bInitialized; + static int m_RefCount; static lua_State* m_pState; };