summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2018-08-17 19:41:53 +0200
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2018-10-03 15:48:15 +0200
commit316447dd0284d79516cc313636e5857f542d6417 (patch)
tree1b2a296f13f8a003662828774bf4f4a7bdd11490
parent36556f2f2c30c10f34d5495a7f7cc735b9b9417a (diff)
tdf#118786 WIN allow nested SendMessage calls
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. Conflicts: vcl/win/app/salinst.cxx Change-Id: I7024b081b26f3545af12a3a3a038fe5e5671af3c Reviewed-on: https://gerrit.libreoffice.org/59275 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de> (cherry picked from commit 35a254750392dcd738481f5d6e8719cee9fb41b3) Reviewed-on: https://gerrit.libreoffice.org/59318 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit 3e392904c558d1f9fc91926511d148762813537e) Reviewed-on: https://gerrit.libreoffice.org/60725 Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
-rw-r--r--vcl/win/app/salinst.cxx41
-rw-r--r--vcl/win/window/salframe.cxx9
2 files changed, 35 insertions, 15 deletions
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index dcea8d53f6d7..f6e17bcf7faa 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -477,6 +477,11 @@ bool ImplSalYield( bool bWait, bool bHandleAllCurrentEvents )
bool bWasMsg = false, bOneEvent = false, bWasTimeoutMsg = false;
ImplSVData *const pSVData = ImplGetSVData();
WinSalTimer* pTimer = static_cast<WinSalTimer*>( pSVData->maSchedCtx.mpSalTimer );
+ const bool bNoYieldLock = GetSalData()->mpInstance->mbNoYieldLock;
+
+ assert( !bNoYieldLock );
+ if ( bNoYieldLock )
+ return false;
sal_uInt32 nCurTicks = 0;
if ( bHandleAllCurrentEvents )
@@ -571,26 +576,46 @@ 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<LRESULT>( function ); \
- pInst->mbNoYieldLock = false; \
+ if (bIsOtherThreadMessage) \
+ { \
+ assert( !pInst->mbNoYieldLock ); \
+ pInst->mbNoYieldLock = true; \
+ nRet = reinterpret_cast<LRESULT>( function ); \
+ pInst->mbNoYieldLock = false; \
+ } \
+ else \
+ { \
+ DBG_TESTSOLARMUTEX(); \
+ nRet = reinterpret_cast<LRESULT>( 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<WinSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
+ SAL_INFO("vcl.gdi.wndproc", "SalComWndProc(nMsg=" << nMsg << ", wParam=" << wParam
+ << ", lParam=" << lParam << "); inSendMsg: " << bIsOtherThreadMessage);
+
switch ( nMsg )
{
case SAL_MSG_THREADYIELD:
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index f34c9d0936cc..27081ed647bd 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -921,13 +921,8 @@ bool WinSalFrame::ReleaseFrameGraphicsDC( WinSalGraphics* pGraphics )
if ( pGraphics->getDefPal() )
SelectPalette( hDC, pGraphics->getDefPal(), TRUE );
pGraphics->DeInitGraphics();
- // we don't want to run the WinProc in the main thread directly
- // so we don't hit the mbNoYieldLock assert
- if ( !pSalData->mpInstance->IsMainThread() )
- SendMessageW( pSalData->mpInstance->mhComWnd, SAL_MSG_RELEASEDC,
- reinterpret_cast<WPARAM>(mhWnd), reinterpret_cast<LPARAM>(hDC) );
- else
- ReleaseDC( mhWnd, hDC );
+ SendMessageW( pSalData->mpInstance->mhComWnd, SAL_MSG_RELEASEDC,
+ reinterpret_cast<WPARAM>(mhWnd), reinterpret_cast<LPARAM>(hDC) );
if ( pGraphics == mpThreadGraphics )
pSalData->mnCacheDCInUse--;
pGraphics->setHDC(nullptr);