linguistic/source/gciterator.cxx |   90 ++++++++++++++++++---------------------
 linguistic/source/gciterator.hxx |   16 +++---
 2 files changed, 50 insertions(+), 56 deletions(-)

New commits:
commit b23019c566f2cbf50dfbec71d258b3e1a9ead312
Author:     Stephan Bergmann <stephan.bergm...@allotropia.de>
AuthorDate: Wed Apr 3 23:32:51 2024 +0200
Commit:     Stephan Bergmann <stephan.bergm...@allotropia.de>
CommitDate: Thu Apr 4 07:06:00 2024 +0200

    Revert "osl::Mutex->std::mutex in GrammarCheckingIterator"
    
    This reverts commit 829fa53fe877d0f0fc33d634fa7fbfbed23b7676, which started 
all
    sorts of `make check` tests to hang for me due to a recursive locking 
attempt in
    
    > #5  std::mutex::lock (this=0x7f6af81e62c0) at 
~/gcc/inst/include/c++/14.0.1/bits/std_mutex.h:113
    > #6  std::unique_lock<std::mutex>::lock (this=<synthetic pointer>) at 
~/gcc/inst/include/c++/14.0.1/bits/unique_lock.h:147
    > #7  std::unique_lock<std::mutex>::unique_lock (this=<synthetic pointer>, 
__m=...) at ~/gcc/inst/include/c++/14.0.1/bits/unique_lock.h:73
    > #8  GrammarCheckingIterator::NextDocId (this=0x7f6af81e6260) at 
linguistic/source/gciterator.cxx:317
    > #9  GrammarCheckingIterator::GetOrCreateDocId 
(this=this@entry=0x7f6af81e6260, xComponent=uno::Reference to (SwXTextDocument 
*) 0x7f6af8430ec8) at linguistic/source/gciterator.cxx:339
    > #10 0x00007f6b3b9e9da9 in GrammarCheckingIterator::startProofreading 
(this=0x7f6af81e6260, xDoc=<optimized out>, xIteratorProvider=<optimized out>) 
at linguistic/source/gciterator.cxx:773
    > #11 0x00007f6b16441ec3 in SwDoc::StartGrammarChecking (this=<optimized 
out>, bSkipStart=bSkipStart@entry=false) at sw/source/core/doc/docnew.cxx:180
    > #12 0x00007f6b164c4eae in sw::DocumentTimerManager::DoIdleJobs 
(this=0x7f6afad005a0) at sw/source/core/doc/DocumentTimerManager.cxx:169
    > #13 0x00007f6b3e83a68b in Scheduler::CallbackTaskScheduling () at 
vcl/source/app/scheduler.cxx:509
    > #14 0x00007f6b3eb1725f in SalTimer::CallCallback (this=<optimized out>) 
at vcl/inc/saltimer.hxx:54
    > #15 SvpSalInstance::CheckTimeout (this=this@entry=0xffebe0, 
bExecuteTimers=bExecuteTimers@entry=true) at vcl/headless/svpinst.cxx:157
    > #16 0x00007f6b3eb1761d in SvpSalInstance::ImplYield 
(this=this@entry=0xffebe0, bWait=bWait@entry=true, 
bHandleAllCurrentEvents=bHandleAllCurrentEvents@entry=false) at 
vcl/headless/svpinst.cxx:395
    > #17 0x00007f6b3eb17cd5 in SvpSalInstance::DoYield (this=0xffebe0, 
bWait=<optimized out>, bHandleAllCurrentEvents=<optimized out>) at 
vcl/headless/svpinst.cxx:467
    > #18 0x00007f6b3e86aa44 in ImplYield (i_bWait=true, i_bAllEvents=false) at 
vcl/source/app/svapp.cxx:394
    > #19 0x00007f6b3e86b13b in Application::Execute () at 
vcl/source/app/svapp.cxx:369
    > #20 0x00007f6b3c8e715f in desktop::Desktop::Main (this=0x7ffe5e22fcb0) at 
desktop/source/app/app.cxx:1615
    > #21 0x00007f6b3e87e6fb in ImplSVMain () at vcl/source/app/svmain.cxx:229
    > #22 0x00007f6b3e87e9c5 in SVMain () at vcl/source/app/svmain.cxx:261
    > #23 0x00007f6b3c91de37 in soffice_main () at 
desktop/source/app/sofficemain.cxx:93
    > #24 0x000000000040078b in sal_main () at desktop/source/app/main.c:51
    > #25 main (argc=argc@entry=8, argv=argv@entry=0x7ffe5e22feb8) at 
desktop/source/app/main.c:49
    
    Change-Id: I60b8b0ba00cae691d6089325e4379a86221dc95b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165764
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de>

diff --git a/linguistic/source/gciterator.cxx b/linguistic/source/gciterator.cxx
index bf37df637f4b..ad85bab95953 100644
--- a/linguistic/source/gciterator.cxx
+++ b/linguistic/source/gciterator.cxx
@@ -273,11 +273,19 @@ css::uno::Any SAL_CALL 
LngXStringKeyMap::getValueByIndex(::sal_Int32 nIndex)
 }
 
 
+osl::Mutex& GrammarCheckingIterator::MyMutex()
+{
+    static osl::Mutex SINGLETON;
+    return SINGLETON;
+}
+
 GrammarCheckingIterator::GrammarCheckingIterator() :
     m_bEnd( false ),
     m_bGCServicesChecked( false ),
     m_nDocIdCounter( 0 ),
-    m_thread(nullptr)
+    m_thread(nullptr),
+    m_aEventListeners( MyMutex() ),
+    m_aNotifyListeners( MyMutex() )
 {
 }
 
@@ -291,7 +299,7 @@ void GrammarCheckingIterator::TerminateThread()
 {
     oslThread t;
     {
-        std::unique_lock aGuard( m_aMutex );
+        ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
         t = m_thread;
         m_thread = nullptr;
         m_bEnd = true;
@@ -314,14 +322,13 @@ bool GrammarCheckingIterator::joinThreads()
 
 sal_Int32 GrammarCheckingIterator::NextDocId()
 {
-    std::unique_lock aGuard( m_aMutex );
+    ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
     m_nDocIdCounter += 1;
     return m_nDocIdCounter;
 }
 
 
 OUString GrammarCheckingIterator::GetOrCreateDocId(
-    std::unique_lock<std::mutex>& /*rGuard*/,
     const uno::Reference< lang::XComponent > &xComponent )
 {
     // internal method; will always be called with locked mutex
@@ -347,7 +354,6 @@ OUString GrammarCheckingIterator::GetOrCreateDocId(
 
 
 void GrammarCheckingIterator::AddEntry(
-    std::unique_lock<std::mutex>& /*rGuard*/,
     const uno::Reference< text::XFlatParagraphIterator >& xFlatParaIterator,
     const uno::Reference< text::XFlatParagraph >& xFlatPara,
     const OUString & rDocId,
@@ -367,6 +373,7 @@ void GrammarCheckingIterator::AddEntry(
     aNewFPEntry.m_bAutomatic    = bAutomatic;
 
     // add new entry to the end of this queue
+    ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
     if (!m_thread)
         m_thread = osl_createThread( lcl_workerfunc, this );
     m_aFPEntriesQueue.push_back( aNewFPEntry );
@@ -479,8 +486,7 @@ void GrammarCheckingIterator::ProcessResult(
         // other sentences left to be checked in this paragraph?
         if (rRes.nStartOfNextSentencePosition < rRes.aText.getLength())
         {
-            std::unique_lock aGuard(m_aMutex);
-            AddEntry( aGuard, rxFlatParagraphIterator, rRes.xFlatParagraph, 
rRes.aDocumentIdentifier, rRes.nStartOfNextSentencePosition, 
bIsAutomaticChecking );
+            AddEntry( rxFlatParagraphIterator, rRes.xFlatParagraph, 
rRes.aDocumentIdentifier, rRes.nStartOfNextSentencePosition, 
bIsAutomaticChecking );
         }
         else    // current paragraph finished
         {
@@ -496,11 +502,8 @@ void GrammarCheckingIterator::ProcessResult(
     {
         // we need to continue with the next paragraph
         if (rxFlatParagraphIterator.is())
-        {
-            std::unique_lock aGuard(m_aMutex);
-            AddEntry(aGuard, rxFlatParagraphIterator, 
rxFlatParagraphIterator->getNextPara(),
+            AddEntry(rxFlatParagraphIterator, 
rxFlatParagraphIterator->getNextPara(),
                      rRes.aDocumentIdentifier, 0, bIsAutomaticChecking);
-        }
     }
 }
 
@@ -528,11 +531,13 @@ GrammarCheckingIterator::getServiceForLocale(const 
lang::Locale& rLocale) const
 
 
 uno::Reference< linguistic2::XProofreader > 
GrammarCheckingIterator::GetGrammarChecker(
-    std::unique_lock<std::mutex>& /*rGuard*/,
     lang::Locale &rLocale )
 {
     uno::Reference< linguistic2::XProofreader > xRes;
 
+    // ---- THREAD SAFE START ----
+    ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
+
     // check supported locales for each grammarchecker if not already done
     if (!m_bGCServicesChecked)
     {
@@ -585,6 +590,7 @@ uno::Reference< linguistic2::XProofreader > 
GrammarCheckingIterator::GetGrammarC
         SAL_INFO("linguistic", "No grammar checker found for \""
                                    << LanguageTag::convertToBcp47(rLocale, 
false) << "\"");
     }
+    // ---- THREAD SAFE END ----
 
     return xRes;
 }
@@ -611,7 +617,7 @@ void GrammarCheckingIterator::DequeueAndCheck()
         // ---- THREAD SAFE START ----
         bool bQueueEmpty = false;
         {
-            std::unique_lock aGuard( m_aMutex );
+            ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
             if (m_bEnd)
             {
                 break;
@@ -628,7 +634,7 @@ void GrammarCheckingIterator::DequeueAndCheck()
             OUString aCurDocId;
             // ---- THREAD SAFE START ----
             {
-                std::unique_lock aGuard( m_aMutex );
+                ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
                 aFPEntryItem        = m_aFPEntriesQueue.front();
                 xFPIterator         = aFPEntryItem.m_xParaIterator;
                 xFlatPara           = aFPEntryItem.m_xPara;
@@ -653,7 +659,7 @@ void GrammarCheckingIterator::DequeueAndCheck()
 
                         // ---- THREAD SAFE START ----
                         {
-                            std::unique_lock aGuard( m_aMutex );
+                            osl::ClearableMutexGuard aGuard(MyMutex());
 
                             sal_Int32 nStartPos = aFPEntryItem.m_nStartIndex;
                             sal_Int32 nSuggestedEnd
@@ -663,10 +669,10 @@ void GrammarCheckingIterator::DequeueAndCheck()
                                        "nSuggestedEndOfSentencePos calculation 
failed?");
 
                             uno::Reference<linguistic2::XProofreader> xGC =
-                                GetGrammarChecker(aGuard, aCurLocale);
+                                GetGrammarChecker(aCurLocale);
                             if (xGC.is())
                             {
-                                aGuard.unlock();
+                                aGuard.clear();
                                 uno::Sequence<beans::PropertyValue> const 
aProps(
                                     lcl_makeProperties(xFlatPara, 
PROOFINFO_MARK_PARAGRAPH));
                                 aRes = xGC->doProofreading(aCurDocId, aCurTxt, 
aCurLocale,
@@ -712,8 +718,7 @@ void GrammarCheckingIterator::DequeueAndCheck()
                         // the paragraph changed meanwhile... (and maybe is 
still edited)
                         // thus we simply continue to ask for the next to be 
checked.
                         uno::Reference< text::XFlatParagraph > xFlatParaNext( 
xFPIterator->getNextPara() );
-                        std::unique_lock aGuard(m_aMutex);
-                        AddEntry( aGuard, xFPIterator, xFlatParaNext, 
aCurDocId, 0, aFPEntryItem.m_bAutomatic );
+                        AddEntry( xFPIterator, xFlatParaNext, aCurDocId, 0, 
aFPEntryItem.m_bAutomatic );
                     }
                 }
                 catch (css::uno::Exception &)
@@ -724,7 +729,7 @@ void GrammarCheckingIterator::DequeueAndCheck()
 
             // ---- THREAD SAFE START ----
             {
-                std::unique_lock aGuard( m_aMutex );
+                ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
                 m_aCurCheckedDocId.clear();
             }
             // ---- THREAD SAFE END ----
@@ -733,7 +738,7 @@ void GrammarCheckingIterator::DequeueAndCheck()
         {
             // ---- THREAD SAFE START ----
             {
-                std::unique_lock aGuard( m_aMutex );
+                ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
                 if (m_bEnd)
                 {
                     break;
@@ -767,13 +772,13 @@ void SAL_CALL GrammarCheckingIterator::startProofreading(
     uno::Reference< lang::XComponent > xComponent( xDoc, uno::UNO_QUERY );
 
     // ---- THREAD SAFE START ----
-    std::unique_lock aGuard( m_aMutex );
+    ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
     if (xPara.is() && xComponent.is())
     {
-        OUString aDocId = GetOrCreateDocId( aGuard, xComponent );
+        OUString aDocId = GetOrCreateDocId( xComponent );
 
         // create new entry and add it to queue
-        AddEntry( aGuard, xFPIterator, xPara, aDocId, 0, bAutomatic );
+        AddEntry( xFPIterator, xPara, aDocId, 0, bAutomatic );
     }
     // ---- THREAD SAFE END ----
 }
@@ -810,12 +815,12 @@ linguistic2::ProofreadingResult SAL_CALL 
GrammarCheckingIterator::checkSentenceA
 
             // ---- THREAD SAFE START ----
             {
-                std::unique_lock aGuard( m_aMutex );
-                aDocId = GetOrCreateDocId( aGuard, xComponent );
+                ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
+                aDocId = GetOrCreateDocId( xComponent );
                 nSuggestedEndOfSentencePos = GetSuggestedEndOfSentence( rText, 
nStartPos, aCurLocale );
                 DBG_ASSERT( nSuggestedEndOfSentencePos > nStartPos, 
"nSuggestedEndOfSentencePos calculation failed?" );
 
-                xGC = GetGrammarChecker( aGuard, aCurLocale );
+                xGC = GetGrammarChecker( aCurLocale );
             }
             // ---- THREAD SAFE START ----
             sal_Int32 nEndPos = -1;
@@ -922,7 +927,7 @@ sal_Bool SAL_CALL GrammarCheckingIterator::isProofreading(
     const uno::Reference< uno::XInterface >& xDoc )
 {
     // ---- THREAD SAFE START ----
-    std::unique_lock aGuard( m_aMutex );
+    ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
 
     bool bRes = false;
 
@@ -973,9 +978,7 @@ void SAL_CALL 
GrammarCheckingIterator::processLinguServiceEvent(
     {
          uno::Reference< uno::XInterface > xThis( getXWeak() );
          linguistic2::LinguServiceEvent aEvent( xThis, 
linguistic2::LinguServiceEventFlags::PROOFREAD_AGAIN );
-         std::unique_lock aGuard( m_aMutex );
          m_aNotifyListeners.notifyEach(
-                aGuard,
                 
&linguistic2::XLinguServiceEventListener::processLinguServiceEvent,
                 aEvent);
     }
@@ -996,8 +999,7 @@ sal_Bool SAL_CALL 
GrammarCheckingIterator::addLinguServiceEventListener(
 {
     if (xListener.is())
     {
-        std::unique_lock aGuard( m_aMutex );
-        m_aNotifyListeners.addInterface( aGuard, xListener );
+        m_aNotifyListeners.addInterface( xListener );
     }
     return true;
 }
@@ -1008,8 +1010,7 @@ sal_Bool SAL_CALL 
GrammarCheckingIterator::removeLinguServiceEventListener(
 {
     if (xListener.is())
     {
-        std::unique_lock aGuard( m_aMutex );
-        m_aNotifyListeners.removeInterface( aGuard, xListener );
+        m_aNotifyListeners.removeInterface( xListener );
     }
     return true;
 }
@@ -1018,16 +1019,13 @@ sal_Bool SAL_CALL 
GrammarCheckingIterator::removeLinguServiceEventListener(
 void SAL_CALL GrammarCheckingIterator::dispose()
 {
     lang::EventObject aEvt( static_cast<linguistic2::XProofreadingIterator 
*>(this) );
-    {
-        std::unique_lock aGuard( m_aMutex );
-        m_aEventListeners.disposeAndClear( aGuard, aEvt );
-    }
+    m_aEventListeners.disposeAndClear( aEvt );
 
     TerminateThread();
 
     // ---- THREAD SAFE START ----
     {
-        std::unique_lock aGuard( m_aMutex );
+        ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
 
         // release all UNO references
 
@@ -1050,8 +1048,7 @@ void SAL_CALL GrammarCheckingIterator::addEventListener(
 {
     if (xListener.is())
     {
-        std::unique_lock aGuard( m_aMutex );
-        m_aEventListeners.addInterface( aGuard, xListener );
+        m_aEventListeners.addInterface( xListener );
     }
 }
 
@@ -1061,8 +1058,7 @@ void SAL_CALL 
GrammarCheckingIterator::removeEventListener(
 {
     if (xListener.is())
     {
-        std::unique_lock aGuard( m_aMutex );
-        m_aEventListeners.removeInterface( aGuard, xListener );
+        m_aEventListeners.removeInterface( xListener );
     }
 }
 
@@ -1081,7 +1077,7 @@ void SAL_CALL GrammarCheckingIterator::disposing( const 
lang::EventObject &rSour
     if (xDoc.is())
     {
         // ---- THREAD SAFE START ----
-        std::unique_lock aGuard( m_aMutex );
+        ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
         m_aDocIdMap.erase( xDoc.get() );
         // ---- THREAD SAFE END ----
     }
@@ -1155,7 +1151,7 @@ void GrammarCheckingIterator::GetConfiguredGCSvcs_Impl()
 
     {
         // ---- THREAD SAFE START ----
-        std::unique_lock aGuard( m_aMutex );
+        ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
         m_aGCImplNamesByLang.swap(aTmpGCImplNamesByLang);
         // ---- THREAD SAFE END ----
     }
@@ -1185,7 +1181,7 @@ void GrammarCheckingIterator::SetServiceList(
     const lang::Locale &rLocale,
     const uno::Sequence< OUString > &rSvcImplNames )
 {
-    std::unique_lock aGuard( m_aMutex );
+    ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
 
     OUString sBcp47 = LanguageTag::convertToBcp47(rLocale, false);
     OUString aImplName;
@@ -1205,7 +1201,7 @@ void GrammarCheckingIterator::SetServiceList(
 uno::Sequence< OUString > GrammarCheckingIterator::GetServiceList(
     const lang::Locale &rLocale ) const
 {
-    std::unique_lock aGuard( m_aMutex );
+    ::osl::Guard< ::osl::Mutex > aGuard( MyMutex() );
 
     const OUString aImplName = getServiceForLocale(rLocale).first;     // 
there is only one grammar checker per language
 
diff --git a/linguistic/source/gciterator.hxx b/linguistic/source/gciterator.hxx
index e56b0ea53e98..62b3a53af8fa 100644
--- a/linguistic/source/gciterator.hxx
+++ b/linguistic/source/gciterator.hxx
@@ -29,13 +29,13 @@
 #include <com/sun/star/util/XChangesBatch.hpp>
 
 #include <cppuhelper/implbase.hxx>
-#include <mutex>
+#include <osl/mutex.hxx>
 #include <osl/conditn.hxx>
 #include <osl/thread.h>
 
 #include <com/sun/star/uno/Any.hxx>
 #include <comphelper/lok.hxx>
-#include <comphelper/interfacecontainer4.hxx>
+#include <comphelper/interfacecontainer3.hxx>
 #include <i18nlangtag/lang.h>
 
 #include <map>
@@ -84,8 +84,6 @@ class GrammarCheckingIterator:
     public LinguDispatcher,
     public comphelper::LibreOfficeKit::ThreadJoinable
 {
-    mutable std::mutex m_aMutex;
-
     //the queue is keeping track of all sentences to be checked
     //every element of this queue is a FlatParagraphEntry struct-object
     typedef std::deque< FPEntry > FPQueue_t;
@@ -116,8 +114,9 @@ class GrammarCheckingIterator:
     oslThread       m_thread;
 
     //! beware of initialization order!
-    comphelper::OInterfaceContainerHelper4<css::lang::XEventListener>  
m_aEventListeners;
-    
comphelper::OInterfaceContainerHelper4<css::linguistic2::XLinguServiceEventListener>
  m_aNotifyListeners;
+    static osl::Mutex& MyMutex();
+    comphelper::OInterfaceContainerHelper3<css::lang::XEventListener>  
m_aEventListeners;
+    
comphelper::OInterfaceContainerHelper3<css::linguistic2::XLinguServiceEventListener>
  m_aNotifyListeners;
 
     css::uno::Reference< css::i18n::XBreakIterator > m_xBreakIterator;
     mutable css::uno::Reference< css::util::XChangesBatch >  m_xUpdateAccess;
@@ -125,10 +124,9 @@ class GrammarCheckingIterator:
     void TerminateThread();
 
     sal_Int32 NextDocId();
-    OUString GetOrCreateDocId( std::unique_lock<std::mutex>& rGuard, const 
css::uno::Reference< css::lang::XComponent > &xComp );
+    OUString GetOrCreateDocId( const css::uno::Reference< 
css::lang::XComponent > &xComp );
 
     void AddEntry(
-            std::unique_lock<std::mutex>& rGuard,
             const css::uno::Reference< css::text::XFlatParagraphIterator >& 
xFlatParaIterator,
             const css::uno::Reference< css::text::XFlatParagraph >& xFlatPara,
             const OUString &rDocId, sal_Int32 nStartIndex, bool bAutomatic );
@@ -140,7 +138,7 @@ class GrammarCheckingIterator:
     sal_Int32 GetSuggestedEndOfSentence( const OUString &rText, sal_Int32 
nSentenceStartPos, const css::lang::Locale &rLocale );
 
     void GetConfiguredGCSvcs_Impl();
-    css::uno::Reference< css::linguistic2::XProofreader > GetGrammarChecker( 
std::unique_lock<std::mutex>& rGuard, css::lang::Locale & rLocale );
+    css::uno::Reference< css::linguistic2::XProofreader > GetGrammarChecker( 
css::lang::Locale & rLocale );
 
     css::uno::Reference< css::util::XChangesBatch > const & GetUpdateAccess() 
const;
 

Reply via email to