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);
FPLSLOG fpLSLog = NULL;
static CRITICAL_SECTION g_CsLog = {0};
static CRITICAL_SECTION g_CsLogDelay = {0};
static int logFound = 0;
void ResetLoggingFlag()
@ -63,23 +66,35 @@ void ResetLoggingFlag()
void InitalizeLitestep()
{
// Use lsapi's methods instead of the stubs
HINSTANCE h = CSystem::RmLoadLibrary(L"lsapi.dll");
if (h != NULL)
InitializeCriticalSection(&g_CsLog);
InitializeCriticalSection(&g_CsLogDelay);
if (!CRainmeter::GetDummyLitestep())
{
fpAddBangCommand = (FPADDBANGCOMMAND)GetProcAddress(h, "AddBangCommand");
fpBitmapToRegion = (FPBITMAPTOREGION)GetProcAddress(h, "BitmapToRegion");
fpGetLitestepWnd = (FPGETLITESTEPWND)GetProcAddress(h, "GetLitestepWnd");
fpGetRCString = (FPGETRCSTRING)GetProcAddress(h, "GetRCString");
//fpGetRCInt = (FPGETRCINT)GetProcAddress(h, "GetRCInt");
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");
// Use lsapi's methods instead of the stubs
HINSTANCE h = CSystem::RmLoadLibrary(L"lsapi.dll");
if (h != NULL)
{
fpAddBangCommand = (FPADDBANGCOMMAND)GetProcAddress(h, "AddBangCommand");
fpBitmapToRegion = (FPBITMAPTOREGION)GetProcAddress(h, "BitmapToRegion");
fpGetLitestepWnd = (FPGETLITESTEPWND)GetProcAddress(h, "GetLitestepWnd");
fpGetRCString = (FPGETRCSTRING)GetProcAddress(h, "GetRCString");
//fpGetRCInt = (FPGETRCINT)GetProcAddress(h, "GetRCInt");
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)
{
// Use the lsapi.dll version of the method if possible
@ -528,14 +543,11 @@ std::wstring ConvertUTF8ToWide(LPCSTR str)
return szWide;
}
BOOL LogInternal(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage)
BOOL LogInternal(int nLevel, LPCTSTR pszModule, ULONGLONG elapsed, LPCTSTR pszMessage)
{
// Add timestamp
static ULONGLONG startTime = CSystem::GetTickCount64();
ULONGLONG time = CSystem::GetTickCount64();
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)
{
@ -621,6 +633,7 @@ BOOL LogInternal(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage)
}
}
}
return TRUE;
}
@ -628,7 +641,50 @@ BOOL LSLog(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage)
{
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;
@ -636,7 +692,7 @@ BOOL LSLog(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage)
void Log(int nLevel, const WCHAR* message)
{
LogInternal(nLevel, L"Rainmeter", message);
LSLog(nLevel, L"Rainmeter", message);
}
void LogWithArgs(int nLevel, const WCHAR* format, ... )
@ -658,7 +714,7 @@ void LogWithArgs(int nLevel, const WCHAR* format, ... )
_set_invalid_parameter_handler(oldHandler);
LogInternal(nLevel, L"Rainmeter", buffer);
LSLog(nLevel, L"Rainmeter", buffer);
va_end(args);
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
void InitalizeLitestep();
void FinalizeLitestep();
// The stubs
BOOL AddBangCommand(LPCSTR command, BangCommand f);

View File

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

View File

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