Fixed deadlock issue when About dialog is opened.

This commit is contained in:
spx 2011-08-31 11:06:35 +00:00
parent 508f8f77ed
commit e721be6456
4 changed files with 81 additions and 30 deletions

View File

@ -54,6 +54,9 @@ FPVAREXPANSION fpVarExpansion = NULL;
typedef BOOL (WINAPI *FPLSLOG)(int nLevel, LPCSTR pszModule, LPCSTR pszMessage); typedef BOOL (WINAPI *FPLSLOG)(int nLevel, LPCSTR pszModule, LPCSTR pszMessage);
FPLSLOG fpLSLog = NULL; FPLSLOG fpLSLog = NULL;
static CRITICAL_SECTION g_CsLog = {0};
static CRITICAL_SECTION g_CsLogDelay = {0};
static int logFound = 0; static int logFound = 0;
void ResetLoggingFlag() void ResetLoggingFlag()
@ -63,23 +66,35 @@ void ResetLoggingFlag()
void InitalizeLitestep() void InitalizeLitestep()
{ {
// Use lsapi's methods instead of the stubs InitializeCriticalSection(&g_CsLog);
HINSTANCE h = CSystem::RmLoadLibrary(L"lsapi.dll"); InitializeCriticalSection(&g_CsLogDelay);
if (h != NULL)
if (!CRainmeter::GetDummyLitestep())
{ {
fpAddBangCommand = (FPADDBANGCOMMAND)GetProcAddress(h, "AddBangCommand"); // Use lsapi's methods instead of the stubs
fpBitmapToRegion = (FPBITMAPTOREGION)GetProcAddress(h, "BitmapToRegion"); HINSTANCE h = CSystem::RmLoadLibrary(L"lsapi.dll");
fpGetLitestepWnd = (FPGETLITESTEPWND)GetProcAddress(h, "GetLitestepWnd"); if (h != NULL)
fpGetRCString = (FPGETRCSTRING)GetProcAddress(h, "GetRCString"); {
//fpGetRCInt = (FPGETRCINT)GetProcAddress(h, "GetRCInt"); fpAddBangCommand = (FPADDBANGCOMMAND)GetProcAddress(h, "AddBangCommand");
fpLSExecute = (FPLSEXECUTE)GetProcAddress(h, "LSExecute"); fpBitmapToRegion = (FPBITMAPTOREGION)GetProcAddress(h, "BitmapToRegion");
fpRemoveBangCommand = (FPREMOVEBANGCOMMAND)GetProcAddress(h, "RemoveBangCommand"); fpGetLitestepWnd = (FPGETLITESTEPWND)GetProcAddress(h, "GetLitestepWnd");
//fpTransparentBltLS = (FPTRANSPARENTBLTLS)GetProcAddress(h, "TransparentBltLS"); fpGetRCString = (FPGETRCSTRING)GetProcAddress(h, "GetRCString");
fpVarExpansion = (FPVAREXPANSION)GetProcAddress(h, "VarExpansion"); //fpGetRCInt = (FPGETRCINT)GetProcAddress(h, "GetRCInt");
fpLSLog = (FPLSLOG)GetProcAddress(h, "_LSLog@12"); fpLSExecute = (FPLSEXECUTE)GetProcAddress(h, "LSExecute");
fpRemoveBangCommand = (FPREMOVEBANGCOMMAND)GetProcAddress(h, "RemoveBangCommand");
//fpTransparentBltLS = (FPTRANSPARENTBLTLS)GetProcAddress(h, "TransparentBltLS");
fpVarExpansion = (FPVAREXPANSION)GetProcAddress(h, "VarExpansion");
fpLSLog = (FPLSLOG)GetProcAddress(h, "_LSLog@12");
}
} }
} }
void FinalizeLitestep()
{
DeleteCriticalSection(&g_CsLog);
DeleteCriticalSection(&g_CsLogDelay);
}
BOOL AddBangCommand(LPCSTR command, BangCommand f) BOOL AddBangCommand(LPCSTR command, BangCommand f)
{ {
// Use the lsapi.dll version of the method if possible // Use the lsapi.dll version of the method if possible
@ -528,14 +543,11 @@ std::wstring ConvertUTF8ToWide(LPCSTR str)
return szWide; return szWide;
} }
BOOL LogInternal(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage) BOOL LogInternal(int nLevel, LPCTSTR pszModule, ULONGLONG elapsed, LPCTSTR pszMessage)
{ {
// Add timestamp // Add timestamp
static ULONGLONG startTime = CSystem::GetTickCount64();
ULONGLONG time = CSystem::GetTickCount64();
WCHAR buffer[128]; WCHAR buffer[128];
_snwprintf_s(buffer, _TRUNCATE, L"%02llu:%02llu:%02llu.%03llu", (time - startTime) / (1000 * 60* 60), ((time - startTime) / (1000 * 60)) % 60, ((time - startTime) / 1000) % 60, (time - startTime) % 1000); _snwprintf_s(buffer, _TRUNCATE, L"%02llu:%02llu:%02llu.%03llu", elapsed / (1000 * 60 * 60), (elapsed / (1000 * 60)) % 60, (elapsed / 1000) % 60, elapsed % 1000);
if (Rainmeter) if (Rainmeter)
{ {
@ -621,6 +633,7 @@ BOOL LogInternal(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage)
} }
} }
} }
return TRUE; return TRUE;
} }
@ -628,7 +641,50 @@ BOOL LSLog(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage)
{ {
if (nLevel != LOG_DEBUG || Rainmeter->GetDebug()) if (nLevel != LOG_DEBUG || Rainmeter->GetDebug())
{ {
return LogInternal(nLevel, pszModule, pszMessage); struct DELAYED_LOG_INFO
{
int level;
std::wstring module;
ULONGLONG elapsed;
std::wstring message;
};
static std::list<DELAYED_LOG_INFO> c_LogDelay;
static ULONGLONG startTime = CSystem::GetTickCount64();
ULONGLONG elapsed = CSystem::GetTickCount64() - startTime;
if (TryEnterCriticalSection(&g_CsLog))
{
// Log the queued messages first
EnterCriticalSection(&g_CsLogDelay);
while (!c_LogDelay.empty())
{
DELAYED_LOG_INFO& logInfo = c_LogDelay.front();
LogInternal(logInfo.level, logInfo.module.c_str(), logInfo.elapsed, logInfo.message.c_str());
c_LogDelay.erase(c_LogDelay.begin());
}
LeaveCriticalSection(&g_CsLogDelay);
// Log the message
BOOL ret = LogInternal(nLevel, pszModule, elapsed, pszMessage);
LeaveCriticalSection(&g_CsLog);
return ret;
}
else
{
// Queue the message
EnterCriticalSection(&g_CsLogDelay);
DELAYED_LOG_INFO logInfo = {nLevel, pszModule, elapsed, pszMessage};
c_LogDelay.push_back(logInfo);
LeaveCriticalSection(&g_CsLogDelay);
}
} }
return TRUE; return TRUE;
@ -636,7 +692,7 @@ BOOL LSLog(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage)
void Log(int nLevel, const WCHAR* message) void Log(int nLevel, const WCHAR* message)
{ {
LogInternal(nLevel, L"Rainmeter", message); LSLog(nLevel, L"Rainmeter", message);
} }
void LogWithArgs(int nLevel, const WCHAR* format, ... ) void LogWithArgs(int nLevel, const WCHAR* format, ... )
@ -658,7 +714,7 @@ void LogWithArgs(int nLevel, const WCHAR* format, ... )
_set_invalid_parameter_handler(oldHandler); _set_invalid_parameter_handler(oldHandler);
LogInternal(nLevel, L"Rainmeter", buffer); LSLog(nLevel, L"Rainmeter", buffer);
va_end(args); va_end(args);
delete [] buffer; delete [] buffer;

View File

@ -34,6 +34,7 @@ typedef void (BangCommand)(HWND sender, LPCSTR args);
// Call this if you want to use lsapi.dll's functions instead of stubs // Call this if you want to use lsapi.dll's functions instead of stubs
void InitalizeLitestep(); void InitalizeLitestep();
void FinalizeLitestep();
// The stubs // The stubs
BOOL AddBangCommand(LPCSTR command, BangCommand f); BOOL AddBangCommand(LPCSTR command, BangCommand f);

View File

@ -1732,13 +1732,10 @@ CRainmeter::CRainmeter() :
m_DisableRDP(false), m_DisableRDP(false),
m_DisableDragging(false), m_DisableDragging(false),
m_Logging(false), m_Logging(false),
m_CsLogData(),
m_CurrentParser(), m_CurrentParser(),
m_Instance(), m_Instance(),
m_GDIplusToken() m_GDIplusToken()
{ {
InitializeCriticalSection(&m_CsLogData);
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
InitCommonControls(); InitCommonControls();
@ -1776,9 +1773,9 @@ CRainmeter::~CRainmeter()
UpdateDesktopWorkArea(true); UpdateDesktopWorkArea(true);
} }
CoUninitialize(); FinalizeLitestep();
DeleteCriticalSection(&m_CsLogData); CoUninitialize();
GdiplusShutdown(m_GDIplusToken); GdiplusShutdown(m_GDIplusToken);
} }
@ -1817,7 +1814,7 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
m_Path = tmpSzPath; m_Path = tmpSzPath;
if (!c_DummyLitestep) InitalizeLitestep(); InitalizeLitestep();
bool bDefaultIniLocation = false; bool bDefaultIniLocation = false;
@ -4273,9 +4270,7 @@ void CRainmeter::AddAboutLogInfo(int level, LPCWSTR time, LPCWSTR message)
{ {
// TODO: Store items in vector // TODO: Store items in vector
EnterCriticalSection(&m_CsLogData);
CDialogAbout::AddLogItem(level, time, message); CDialogAbout::AddLogItem(level, time, message);
LeaveCriticalSection(&m_CsLogData);
} }
void CRainmeter::SetLogging(bool logging) void CRainmeter::SetLogging(bool logging)

View File

@ -328,7 +328,6 @@ private:
bool m_Logging; bool m_Logging;
std::list<LOG_INFO> m_LogData; std::list<LOG_INFO> m_LogData;
CRITICAL_SECTION m_CsLogData;
std::wstring m_ConfigEditor; std::wstring m_ConfigEditor;
std::wstring m_LogViewer; std::wstring m_LogViewer;