From b60d7bdd9079badd1c7c99481adcc4e88fe4852e Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Wed, 22 Feb 2012 06:42:52 +0000 Subject: [PATCH] Fixed crash that could occur when using RmExecute from separate thread (in WebParser) --- Library/Export.cpp | 3 ++- Library/MeterWindow.cpp | 8 ++++---- Library/MeterWindow.h | 4 ++-- Library/Rainmeter.cpp | 5 ++++- Library/Rainmeter.h | 1 + Library/System.cpp | 2 +- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Library/Export.cpp b/Library/Export.cpp index d676a664..fcc07d61 100644 --- a/Library/Export.cpp +++ b/Library/Export.cpp @@ -90,7 +90,8 @@ void __stdcall RmExecute(void* skin, LPCWSTR command) CMeterWindow* mw = (CMeterWindow*)skin; if (command) { - Rainmeter->ExecuteCommand(command, mw); + // WM_RAINMETER_EXECUTE used instead of ExecuteCommand for thread-safety + SendMessage(Rainmeter->GetWindow(), WM_RAINMETER_EXECUTE, (WPARAM)mw, (LPARAM)command); } } diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index b4a91f7f..2fbe4e1b 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -700,7 +700,7 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const std::vector& ar { case BANG_REFRESH: // Refresh needs to be delayed since it crashes if done during Update() - PostMessage(m_Window, WM_DELAYED_REFRESH, (WPARAM)NULL, (LPARAM)NULL); + PostMessage(m_Window, WM_METERWINDOW_DELAYED_REFRESH, (WPARAM)NULL, (LPARAM)NULL); break; case BANG_REDRAW: @@ -4638,8 +4638,8 @@ LRESULT CALLBACK CMeterWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR MESSAGE(OnMiddleButtonDoubleClick, WM_NCMBUTTONDBLCLK) MESSAGE(OnWindowPosChanging, WM_WINDOWPOSCHANGING) MESSAGE(OnCopyData, WM_COPYDATA) - MESSAGE(OnDelayedRefresh, WM_DELAYED_REFRESH) - MESSAGE(OnDelayedMove, WM_DELAYED_MOVE) + MESSAGE(OnDelayedRefresh, WM_METERWINDOW_DELAYED_REFRESH) + MESSAGE(OnDelayedMove, WM_METERWINDOW_DELAYED_MOVE) MESSAGE(OnDwmColorChange, WM_DWMCOLORIZATIONCOLORCHANGED) MESSAGE(OnDwmCompositionChange, WM_DWMCOMPOSITIONCHANGED) MESSAGE(OnSettingChange, WM_SETTINGCHANGE) @@ -4706,7 +4706,7 @@ LRESULT CMeterWindow::OnDelayedMove(UINT uMsg, WPARAM wParam, LPARAM lParam) else { // With copy transparency we'll do a full refresh - PostMessage(m_Window, WM_DELAYED_REFRESH, (WPARAM)NULL, (LPARAM)NULL); + PostMessage(m_Window, WM_METERWINDOW_DELAYED_REFRESH, (WPARAM)NULL, (LPARAM)NULL); } return 0; diff --git a/Library/MeterWindow.h b/Library/MeterWindow.h index 9b57a505..5de8fbe2 100644 --- a/Library/MeterWindow.h +++ b/Library/MeterWindow.h @@ -32,8 +32,8 @@ #define REJECT_MESSAGE(msg) case msg: return 0; #define END_MESSAGEPROC } return DefWindowProc(hWnd, uMsg, wParam, lParam); -#define WM_DELAYED_REFRESH WM_APP + 1 -#define WM_DELAYED_MOVE WM_APP + 3 +#define WM_METERWINDOW_DELAYED_REFRESH WM_APP + 1 +#define WM_METERWINDOW_DELAYED_MOVE WM_APP + 3 #define METERWINDOW_CLASS_NAME L"RainmeterMeterWindow" diff --git a/Library/Rainmeter.cpp b/Library/Rainmeter.cpp index 5a5fe781..4a8ccfaa 100644 --- a/Library/Rainmeter.cpp +++ b/Library/Rainmeter.cpp @@ -1102,6 +1102,10 @@ LRESULT CALLBACK CRainmeter::MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP } break; + case WM_RAINMETER_EXECUTE: + Rainmeter->ExecuteCommand((const WCHAR*)lParam, (CMeterWindow*)wParam); + break; + default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } @@ -2090,7 +2094,6 @@ void CRainmeter::ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow) } } - /* ** Executes command when current processing is done. ** diff --git a/Library/Rainmeter.h b/Library/Rainmeter.h index a6fee1e6..39a1d261 100644 --- a/Library/Rainmeter.h +++ b/Library/Rainmeter.h @@ -44,6 +44,7 @@ #define WM_RAINMETER_DELAYED_REFRESH_ALL WM_APP + 0 #define WM_RAINMETER_DELAYED_EXECUTE WM_APP + 1 +#define WM_RAINMETER_EXECUTE WM_APP + 2 struct GlobalConfig { diff --git a/Library/System.cpp b/Library/System.cpp index c682da66..01ad0af7 100644 --- a/Library/System.cpp +++ b/Library/System.cpp @@ -1009,7 +1009,7 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP std::map::const_iterator iter = Rainmeter->GetAllMeterWindows().begin(); for ( ; iter != Rainmeter->GetAllMeterWindows().end(); ++iter) { - PostMessage((*iter).second->GetWindow(), WM_DELAYED_MOVE, (WPARAM)uMsg, (LPARAM)0); + PostMessage((*iter).second->GetWindow(), WM_METERWINDOW_DELAYED_MOVE, (WPARAM)uMsg, (LPARAM)0); } } break;