From 3e392904c558d1f9fc91926511d148762813537e Mon Sep 17 00:00:00 2001 From: Jan-Marek Glogowski Date: Fri, 17 Aug 2018 19:41:53 +0200 Subject: tdf#118786 WIN allow nested SendMessage calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This bug trips "assert( !pInst->mbNoYieldLock )". There is already a special case, introduced in commit 4baec725e0dc ("WIN run main thread redirects ignoring SolarMutex"), to prevent tripping the assert for a nested SendMessage call. So this implements a general solution for nested SendMessage calls. We just have to prevent yielding in a call from an other thread, as the sending thread still owns the SolarMutex. This way we can also drop the special handling in WinSalFrame::ReleaseFrameGraphicsDC. Change-Id: I7024b081b26f3545af12a3a3a038fe5e5671af3c Reviewed-on: https://gerrit.libreoffice.org/59275 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski (cherry picked from commit 35a254750392dcd738481f5d6e8719cee9fb41b3) Reviewed-on: https://gerrit.libreoffice.org/59318 Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- vcl/win/app/salinst.cxx | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'vcl/win/app') diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx index c0bd18f85627..4e57b8406217 100644 --- a/vcl/win/app/salinst.cxx +++ b/vcl/win/app/salinst.cxx @@ -468,6 +468,11 @@ bool ImplSalYield( bool bWait, bool bHandleAllCurrentEvents ) bool bWasMsg = false, bOneEvent = false, bWasTimeoutMsg = false; ImplSVData *const pSVData = ImplGetSVData(); WinSalTimer* pTimer = static_cast( pSVData->maSchedCtx.mpSalTimer ); + const bool bNoYieldLock = GetSalData()->mpInstance->mbNoYieldLock; + + assert( !bNoYieldLock ); + if ( bNoYieldLock ) + return false; sal_uInt32 nCurTicks = 0; if ( bHandleAllCurrentEvents ) @@ -562,27 +567,45 @@ bool WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) #define CASE_NOYIELDLOCK( salmsg, function ) \ case salmsg: \ - assert( !pInst->mbNoYieldLock ); \ - pInst->mbNoYieldLock = true; \ - function; \ - pInst->mbNoYieldLock = false; \ + if (bIsOtherThreadMessage) \ + { \ + assert( !pInst->mbNoYieldLock ); \ + pInst->mbNoYieldLock = true; \ + function; \ + pInst->mbNoYieldLock = false; \ + } \ + else \ + { \ + DBG_TESTSOLARMUTEX(); \ + function; \ + } \ break; #define CASE_NOYIELDLOCK_RESULT( salmsg, function ) \ case salmsg: \ - assert( !pInst->mbNoYieldLock ); \ - pInst->mbNoYieldLock = true; \ - nRet = reinterpret_cast( function ); \ - pInst->mbNoYieldLock = false; \ + if (bIsOtherThreadMessage) \ + { \ + assert( !pInst->mbNoYieldLock ); \ + pInst->mbNoYieldLock = true; \ + nRet = reinterpret_cast( function ); \ + pInst->mbNoYieldLock = false; \ + } \ + else \ + { \ + DBG_TESTSOLARMUTEX(); \ + nRet = reinterpret_cast( function ); \ + } \ break; LRESULT CALLBACK SalComWndProc( HWND, UINT nMsg, WPARAM wParam, LPARAM lParam, bool& rDef ) { + const BOOL bIsOtherThreadMessage = InSendMessage(); LRESULT nRet = 0; WinSalInstance *pInst = GetSalData()->mpInstance; WinSalTimer *const pTimer = static_cast( ImplGetSVData()->maSchedCtx.mpSalTimer ); -SAL_INFO("vcl.gdi.wndproc", "SalComWndProc(nMsg=" << nMsg << ", wParam=" << wParam << ", lParam=" << lParam << ")"); + SAL_INFO("vcl.gdi.wndproc", "SalComWndProc(nMsg=" << nMsg << ", wParam=" << wParam + << ", lParam=" << lParam << "); inSendMsg: " << bIsOtherThreadMessage); switch ( nMsg ) { -- cgit v1.2.3