include/vcl/status.hxx       |    2 ++
 vcl/source/window/status.cxx |   32 ++++++++++++++++++++++++--------
 2 files changed, 26 insertions(+), 8 deletions(-)

New commits:
commit 6c32fade56c56dcb7ef3101d27dbba0226825c69
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Fri Sep 9 09:26:15 2022 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri Sep 16 18:30:59 2022 +0200

    only "PaintImmediately" the statusbar itself (and optional children)
    
    PaintImmediately normally checks to see if there are paints pending
    on any of the original candidates parents, and if there are, optimizes
    painting by painting from the top windows that is avaiting being
    painted.
    
    But in JunitTest_sc_unoapi_3 sometimes the ScGridWindow parent of the
    StatusBar happens to have outstanding paint requests when the immediate
    paint of the StatusBar is requested and there is deadlock on calling
    ScGridWindow::Paint where the soffice main thread wants to lock the
    SolarMutex at
    
    > #0: 0x00000001a110e270 libsystem_kernel.dylib`__psynch_cvwait + 8
    > #1: 0x00000001a114883c libsystem_pthread.dylib`_pthread_cond_wait + 1236
    > #2: 0x0000000101081dd8 
libc++.1.0.dylib`std::__1::condition_variable::wait at 
~/llvm/build/include/c++/v1/__threading_support:337:10
    > #3: 0x0000000101081dd4 
libc++.1.0.dylib`std::__1::condition_variable::wait at 
~/github.com/llvm/llvm-project/libcxx/src/condition_variable.cpp:46:14
    > #4: 0x0000000112a011d4 libvclplug_osxlo.dylib`void 
std::__1::condition_variable::wait<SalYieldMutex::doAcquire(unsigned int)::$_0> 
at ~/llvm/inst/include/c++/v1/__mutex_base:398:9
    > #5: 0x0000000112a00f98 libvclplug_osxlo.dylib`SalYieldMutex::doAcquire at 
vcl/osx/salinst.cxx:221:36
    > #6: 0x0000000115e6b920 libvcllo.dylib`comphelper::SolarMutex::acquire at 
include/comphelper/solarmutex.hxx:86:5
    > #7: 0x0000000116637178 libvcllo.dylib`SalInstance::AcquireYieldMutex at 
vcl/source/app/salvtables.cxx:149:73
    > #8: 0x00000001166f0c38 libvcllo.dylib`Application::AcquireSolarMutex at 
vcl/source/app/svapp.cxx:594:25
    > #9: 0x0000000112a07b38 
libvclplug_osxlo.dylib`SolarMutexReleaser::~SolarMutexReleaser at 
include/vcl/svapp.hxx:1447:29
    > #10: 0x0000000112a03320 
libvclplug_osxlo.dylib`SolarMutexReleaser::~SolarMutexReleaser at 
include/vcl/svapp.hxx:1447:27
    > #11: 0x0000000112a02d40 libvclplug_osxlo.dylib`AquaSalInstance::DoYield 
at vcl/osx/salinst.cxx:559:9
    > #12: 0x00000001166f01c0 libvcllo.dylib`ImplYield at 
vcl/source/app/svapp.cxx:475:48
    > #13: 0x00000001166efbc8 libvcllo.dylib`Application::Yield at 
vcl/source/app/svapp.cxx:559:5
    > #14: 0x00000001166ef958 libvcllo.dylib`Application::Execute at 
vcl/source/app/svapp.cxx:453:13
    > #15: 0x00000001017a41a8 libsofficeapp.dylib`desktop::Desktop::Main at 
desktop/source/app/app.cxx:1604:13
    
    while another thread
    
    > #0: 0x00000001a110e270 libsystem_kernel.dylib`__psynch_cvwait + 8
    > #1: 0x00000001a114883c libsystem_pthread.dylib`_pthread_cond_wait + 1236
    > #2: 0x00000001a20e87c8 Foundation`-[NSOperation waitUntilFinished] + 580
    > #3: 0x00000001a11d8210 CoreFoundation`_CFXNotificationPost + 812
    > #4: 0x00000001a209dc98 Foundation`-[NSNotificationCenter 
postNotificationName:object:userInfo:] + 96
    > #5: 0x00000001a3d6de0c AppKit`-[NSMenu insertItem:atIndex:] + 624
    > #6: 0x00000001a3f92784 AppKit`-[NSApplication(NSServicesMenuPrivate) 
_fillSpellCheckerPopupButton:] + 1888
    > #7: 0x00000001a3f91bf0 AppKit`-[NSSpellChecker 
_fillSpellCheckerPopupButton:] + 84
    > #8: 0x00000001a3f90ae8 AppKit`-[NSSpellChecker init] + 284
    > #9: 0x00000001a3f909bc AppKit`__36+[NSSpellChecker 
sharedSpellChecker]_block_invoke + 20
    > #10: 0x00000001a0f841b4 libdispatch.dylib`_dispatch_client_callout + 20
    > #11: 0x00000001a0f85a34 libdispatch.dylib`_dispatch_once_callout + 32
    > #12: 0x00000001a3f909a4 AppKit`+[NSSpellChecker sharedSpellChecker] + 140
    > #13: 0x000000028e51d364 
libMacOSXSpelllo.dylib`MacSpellChecker::getLocales at 
lingucomponent/source/spellcheck/macosxspell/macspellimp.mm:117:42
    > #14: 0x00000001120a99d8 
liblnglo.dylib`LngSvcMgr::GetAvailableSpellSvcs_Impl at 
linguistic/source/lngsvcmgr.cxx:963:67
    > #15: 0x00000001120ad1dc liblnglo.dylib`LngSvcMgr::getAvailableServices at 
linguistic/source/lngsvcmgr.cxx:1381:9
    > #16: 0x00000001120ada4c liblnglo.dylib`LngSvcMgr::getAvailableLocales at 
linguistic/source/lngsvcmgr.cxx:1445:42
    > #17: 0x00000001120a1d28 liblnglo.dylib`LngSvcMgr::UpdateAll at 
linguistic/source/lngsvcmgr.cxx:657:49
    > #18: 0x00000001120a0fec liblnglo.dylib`LngSvcMgr::LngSvcMgr at 
linguistic/source/lngsvcmgr.cxx:414:5
    > #19: 0x00000001120a2c50 liblnglo.dylib`LngSvcMgr::LngSvcMgr at 
linguistic/source/lngsvcmgr.cxx:402:1
    > #20: 0x00000001120b1248 
liblnglo.dylib`::linguistic_LngSvcMgr_get_implementation at 
linguistic/source/lngsvcmgr.cxx:1826:30
    [...]
    > #30: 0x000000010449a164 
libeditenglo.dylib`com::sun::star::linguistic2::LinguServiceManager::create at 
workdir/UnoApiHeadersTarget/offapi/normal/com/sun/star/linguistic2/LinguServiceManager.hpp:38:129
    > #31: 0x00000001044973d4 libeditenglo.dylib`GetLngSvcMgr_Impl at 
editeng/source/misc/unolingu.cxx:60:52
    > #32: 0x000000010449bbb0 libeditenglo.dylib`(anonymous 
namespace)::SpellDummy_Impl::GetSpell_Impl at 
editeng/source/misc/unolingu.cxx:216:61
    > #33: 0x000000010449b548 libeditenglo.dylib`(anonymous 
namespace)::SpellDummy_Impl::isValid at editeng/source/misc/unolingu.cxx:248:5
    > #34: 0x000000010439f2a0 
libeditenglo.dylib`ImpEditEngine::DoOnlineSpelling at 
editeng/source/editeng/impedit4.cxx:2268:37
    > #35: 0x00000001042a3a14 
libeditenglo.dylib`EditEngine::CompleteOnlineSpelling at 
editeng/source/editeng/editeng.cxx:2394:25
    > #36: 0x000000028fb26974 
libsclo.dylib`sc::SpellCheckContext::ensureResults at 
sc/source/ui/view/spellcheckcontext.cxx:339:15
    > #37: 0x000000028fb2648c libsclo.dylib`sc::SpellCheckContext::isMisspelled 
const at sc/source/ui/view/spellcheckcontext.cxx:219:43
    > #38: 0x000000028fabd63c libsclo.dylib`ScOutputData::LayoutStrings at 
sc/source/ui/view/output2.cxx:1640:61
    > #39: 0x000000028fabc79c libsclo.dylib`ScOutputData::DrawStrings at 
sc/source/ui/view/output2.cxx:1471:5
    > #40: 0x000000028fa788e4 libsclo.dylib`ScGridWindow::DrawContent at 
sc/source/ui/view/gridwin4.cxx:914:21
    [...]
    > #59: 0x0000000115d6a9c0 libvcllo.dylib`vcl::Window::ImplCallPaint at 
vcl/source/window/paint.cxx:623:1
    > #60: 0x0000000115d6cc78 libvcllo.dylib`vcl::Window::PaintImmediately at 
vcl/source/window/paint.cxx:1335:24
    > #61: 0x0000000115f47d7c libvcllo.dylib`StatusBar::StartProgressMode at 
vcl/source/window/status.cxx:1327:9
    > #62: 0x00000001066ff8c4 
libfwklo.dylib`framework::ProgressBarWrapper::start at 
framework/source/uielement/progressbarwrapper.cxx:111:21
    > #63: 0x000000010671edfc 
libfwklo.dylib`framework::StatusIndicatorInterfaceWrapper::start at 
framework/source/uielement/statusindicatorinterfacewrapper.cxx:50:27
    > #64: 0x00000001099ae138 libsfxlo.dylib`SfxProgress::SetState at 
sfx2/source/bastyp/progress.cxx:230:32
    > #65: 0x000000028e94e558 libsclo.dylib`ScProgress::SetState at 
sc/inc/progress.hxx:85:52
    > #66: 0x000000028ec7f954 libsclo.dylib`ScTable::Sort at 
sc/source/core/data/table3.cxx:1817:28
    > #67: 0x000000028e931380 libsclo.dylib`ScDocument::Sort at 
sc/source/core/data/documen3.cxx:1450:23
    > #68: 0x000000028f43ad90 libsclo.dylib`ScDBDocFunc::Sort at 
sc/source/ui/docshell/dbdocfun.cxx:611:14
    > #69: 0x000000028f798e18 libsclo.dylib`ScCellRangeObj::sort at 
sc/source/ui/unoobj/cellsuno.cxx:5317:17
    > #70: 0x0000000106268964 libgcc3_uno.dylib`callVirtualFunction at 
bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx:38:5
    [...]
    > #73: 0x000000012252f650 
libbinaryurplo.dylib`binaryurp::IncomingRequest::execute_throw const at 
binaryurp/source/incomingrequest.cxx:236:13
    
    Change-Id: Iecfbc7673a2c67851aede3f7ca8be24ee75d1b21
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139713
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/vcl/status.hxx b/include/vcl/status.hxx
index 91a6ed64374f..0ae1a68b8251 100644
--- a/include/vcl/status.hxx
+++ b/include/vcl/status.hxx
@@ -101,6 +101,8 @@ private:
     SAL_DLLPRIVATE tools::Rectangle ImplGetItemRectPos( sal_uInt16 nPos ) 
const;
     SAL_DLLPRIVATE sal_uInt16    ImplGetFirstVisiblePos() const;
 
+    SAL_DLLPRIVATE void      PaintSelfAndChildrenImmediately();
+
 protected:
     virtual void ApplySettings(vcl::RenderContext& rRenderContext) override;
 
diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx
index 81ce41db73e7..7440e33de02e 100644
--- a/vcl/source/window/status.cxx
+++ b/vcl/source/window/status.cxx
@@ -1123,6 +1123,22 @@ tools::Long StatusBar::GetItemOffset( sal_uInt16 nItemId 
) const
     return 0;
 }
 
+void StatusBar::PaintSelfAndChildrenImmediately()
+{
+    WindowImpl* pWindowImpl = ImplGetWindowImpl();
+    const bool bOrigOverlapWin = pWindowImpl->mbOverlapWin;
+    // Temporarily set mbOverlapWin so that any parent windows of StatusBar
+    // that happen to have accumulated Invalidates are not taken as the root
+    // paint candidate from which to paint the paint hierarchy. So we limit the
+    // paint here to this statusbar and its children, disabling the
+    // optimization to bundle pending paints together and suppressing any
+    // unexpected side effects of entering parent window paint handlers if this
+    // call is not from the primordial thread.
+    pWindowImpl->mbOverlapWin = true;
+    PaintImmediately();
+    pWindowImpl->mbOverlapWin = bOrigOverlapWin;
+}
+
 void StatusBar::SetItemText( sal_uInt16 nItemId, const OUString& rText, int 
nCharsWidth )
 {
     sal_uInt16 nPos = GetItemPos( nItemId );
@@ -1166,7 +1182,7 @@ void StatusBar::SetItemText( sal_uInt16 nItemId, const 
OUString& rText, int nCha
     {
         tools::Rectangle aRect = ImplGetItemRectPos(nPos);
         Invalidate(aRect);
-        PaintImmediately();
+        PaintSelfAndChildrenImmediately();
     }
 }
 
@@ -1220,7 +1236,7 @@ void StatusBar::SetItemData( sal_uInt16 nItemId, void* 
pNewData )
     {
         tools::Rectangle aRect = ImplGetItemRectPos(nPos);
         Invalidate(aRect, InvalidateFlags::NoErase);
-        PaintImmediately();
+        PaintSelfAndChildrenImmediately();
     }
 }
 
@@ -1249,7 +1265,7 @@ void StatusBar::RedrawItem(sal_uInt16 nItemId)
     {
         tools::Rectangle aRect = ImplGetItemRectPos(nPos);
         Invalidate(aRect);
-        PaintImmediately();
+        PaintSelfAndChildrenImmediately();
     }
 }
 
@@ -1324,7 +1340,7 @@ void StatusBar::StartProgressMode( const OUString& rText )
     if ( IsReallyVisible() )
     {
         Invalidate();
-        PaintImmediately();
+        PaintSelfAndChildrenImmediately();
     }
 }
 
@@ -1345,7 +1361,7 @@ void StatusBar::SetProgressValue( sal_uInt16 nNewPercent )
         if ((nTime_ms - mnLastProgressPaint_ms) > 100)
         {
             Invalidate(maPrgsFrameRect);
-            PaintImmediately();
+            PaintSelfAndChildrenImmediately();
             mnLastProgressPaint_ms = nTime_ms;
         }
     }
@@ -1361,7 +1377,7 @@ void StatusBar::EndProgressMode()
     if ( IsReallyVisible() )
     {
         Invalidate();
-        PaintImmediately();
+        PaintSelfAndChildrenImmediately();
     }
 }
 
@@ -1378,7 +1394,7 @@ void StatusBar::SetText(const OUString& rText)
         {
             Invalidate();
             Window::SetText(rText);
-            PaintImmediately();
+            PaintSelfAndChildrenImmediately();
         }
     }
     else if (mbProgressMode)
@@ -1387,7 +1403,7 @@ void StatusBar::SetText(const OUString& rText)
         if (IsReallyVisible())
         {
             Invalidate();
-            PaintImmediately();
+            PaintSelfAndChildrenImmediately();
         }
     }
     else

Reply via email to