ucb/source/cacher/cacheddynamicresultset.cxx     |   10 -
 ucb/source/cacher/cacheddynamicresultset.hxx     |    4 
 ucb/source/cacher/cacheddynamicresultsetstub.cxx |   10 -
 ucb/source/cacher/cacheddynamicresultsetstub.hxx |    4 
 ucb/source/cacher/dynamicresultsetwrapper.cxx    |  158 ++++++++++-------------
 ucb/source/cacher/dynamicresultsetwrapper.hxx    |    6 
 6 files changed, 90 insertions(+), 102 deletions(-)

New commits:
commit db20a13d452ac5599416f64729d964829536a033
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Wed Oct 2 19:31:32 2024 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Thu Oct 3 15:26:49 2024 +0200

    cid#1607746 Data race condition
    
    and
    cid#1608428 Data race condition
    cid#1607985 Data race condition
    cid#1607894 Data race condition
    cid#1607463 Data race condition
    cid#1607218 Data race condition
    
    Change-Id: Ifb30dd8490f41e06d47442c3a2b090b184932a4b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174408
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Tested-by: Jenkins

diff --git a/ucb/source/cacher/cacheddynamicresultset.cxx 
b/ucb/source/cacher/cacheddynamicresultset.cxx
index c9f8933b22f6..e69191e71096 100644
--- a/ucb/source/cacher/cacheddynamicresultset.cxx
+++ b/ucb/source/cacher/cacheddynamicresultset.cxx
@@ -47,29 +47,27 @@ CachedDynamicResultSet::~CachedDynamicResultSet()
 
 //virtual
 void CachedDynamicResultSet
-    ::impl_InitResultSetOne( const Reference< XResultSet >& xResultSet )
+    ::impl_InitResultSetOne( std::unique_lock<std::mutex>& rGuard, const 
Reference< XResultSet >& xResultSet )
 {
-    DynamicResultSetWrapper::impl_InitResultSetOne( xResultSet );
+    DynamicResultSetWrapper::impl_InitResultSetOne( rGuard, xResultSet );
     OSL_ENSURE( m_xSourceResultOne.is(), "need source resultset" );
 
     Reference< XResultSet > xCache(
         new CachedContentResultSet( m_xContext, m_xSourceResultOne, 
m_xContentIdentifierMapping ) );
 
-    std::unique_lock aGuard( m_aMutex );
     m_xMyResultOne = std::move(xCache);
 }
 
 //virtual
 void CachedDynamicResultSet
-    ::impl_InitResultSetTwo( const Reference< XResultSet >& xResultSet )
+    ::impl_InitResultSetTwo( std::unique_lock<std::mutex>& rGuard, const 
Reference< XResultSet >& xResultSet )
 {
-    DynamicResultSetWrapper::impl_InitResultSetTwo( xResultSet );
+    DynamicResultSetWrapper::impl_InitResultSetTwo( rGuard, xResultSet );
     OSL_ENSURE( m_xSourceResultTwo.is(), "need source resultset" );
 
     Reference< XResultSet > xCache(
         new CachedContentResultSet( m_xContext, m_xSourceResultTwo, 
m_xContentIdentifierMapping ) );
 
-    std::unique_lock aGuard( m_aMutex );
     m_xMyResultTwo = std::move(xCache);
 }
 
diff --git a/ucb/source/cacher/cacheddynamicresultset.hxx 
b/ucb/source/cacher/cacheddynamicresultset.hxx
index 76075b98eb20..814b57afc957 100644
--- a/ucb/source/cacher/cacheddynamicresultset.hxx
+++ b/ucb/source/cacher/cacheddynamicresultset.hxx
@@ -37,9 +37,9 @@ class CachedDynamicResultSet
 
 protected:
     virtual void
-    impl_InitResultSetOne( const css::uno::Reference< css::sdbc::XResultSet >& 
xResultSet ) override;
+    impl_InitResultSetOne( std::unique_lock<std::mutex>& rGuard, const 
css::uno::Reference< css::sdbc::XResultSet >& xResultSet ) override;
     virtual void
-    impl_InitResultSetTwo( const css::uno::Reference< css::sdbc::XResultSet >& 
xResultSet ) override;
+    impl_InitResultSetTwo( std::unique_lock<std::mutex>& rGuard, const 
css::uno::Reference< css::sdbc::XResultSet >& xResultSet ) override;
 
 public:
     CachedDynamicResultSet( css::uno::Reference< css::ucb::XDynamicResultSet > 
const & xOrigin
diff --git a/ucb/source/cacher/cacheddynamicresultsetstub.cxx 
b/ucb/source/cacher/cacheddynamicresultsetstub.cxx
index eac5d7db439d..f5decb5e5506 100644
--- a/ucb/source/cacher/cacheddynamicresultsetstub.cxx
+++ b/ucb/source/cacher/cacheddynamicresultsetstub.cxx
@@ -48,29 +48,27 @@ CachedDynamicResultSetStub::~CachedDynamicResultSetStub()
 
 //virtual
 void CachedDynamicResultSetStub
-    ::impl_InitResultSetOne( const Reference< XResultSet >& xResultSet )
+    ::impl_InitResultSetOne( std::unique_lock<std::mutex>& rGuard, const 
Reference< XResultSet >& xResultSet )
 {
-    DynamicResultSetWrapper::impl_InitResultSetOne( xResultSet );
+    DynamicResultSetWrapper::impl_InitResultSetOne( rGuard, xResultSet );
     OSL_ENSURE( m_xSourceResultOne.is(), "need source resultset" );
 
     Reference< XResultSet > xStub(
         new CachedContentResultSetStub( m_xSourceResultOne ) );
 
-    std::unique_lock aGuard( m_aMutex );
     m_xMyResultOne = std::move(xStub);
 }
 
 //virtual
 void CachedDynamicResultSetStub
-    ::impl_InitResultSetTwo( const Reference< XResultSet >& xResultSet )
+    ::impl_InitResultSetTwo( std::unique_lock<std::mutex>& rGuard, const 
Reference< XResultSet >& xResultSet )
 {
-    DynamicResultSetWrapper::impl_InitResultSetTwo( xResultSet );
+    DynamicResultSetWrapper::impl_InitResultSetTwo( rGuard, xResultSet );
     OSL_ENSURE( m_xSourceResultTwo.is(), "need source resultset" );
 
     Reference< XResultSet > xStub(
         new CachedContentResultSetStub( m_xSourceResultTwo ) );
 
-    std::unique_lock aGuard( m_aMutex );
     m_xMyResultTwo = std::move(xStub);
 }
 
diff --git a/ucb/source/cacher/cacheddynamicresultsetstub.hxx 
b/ucb/source/cacher/cacheddynamicresultsetstub.hxx
index b148efec9d5e..b7d19a1b78b4 100644
--- a/ucb/source/cacher/cacheddynamicresultsetstub.hxx
+++ b/ucb/source/cacher/cacheddynamicresultsetstub.hxx
@@ -34,9 +34,9 @@ class CachedDynamicResultSetStub
 {
 protected:
     virtual void
-    impl_InitResultSetOne( const css::uno::Reference< css::sdbc::XResultSet >& 
xResultSet ) override;
+    impl_InitResultSetOne( std::unique_lock<std::mutex>& rGuard, const 
css::uno::Reference< css::sdbc::XResultSet >& xResultSet ) override;
     virtual void
-    impl_InitResultSetTwo( const css::uno::Reference< css::sdbc::XResultSet >& 
xResultSet ) override;
+    impl_InitResultSetTwo( std::unique_lock<std::mutex>& rGuard, const 
css::uno::Reference< css::sdbc::XResultSet >& xResultSet ) override;
 
 public:
     CachedDynamicResultSetStub( css::uno::Reference< 
css::ucb::XDynamicResultSet > const & xOrigin
diff --git a/ucb/source/cacher/dynamicresultsetwrapper.cxx 
b/ucb/source/cacher/dynamicresultsetwrapper.cxx
index db881dad492f..ffa698799baa 100644
--- a/ucb/source/cacher/dynamicresultsetwrapper.cxx
+++ b/ucb/source/cacher/dynamicresultsetwrapper.cxx
@@ -81,26 +81,23 @@ void DynamicResultSetWrapper::impl_deinit()
     m_xMyListenerImpl->impl_OwnerDies();
 }
 
-void DynamicResultSetWrapper::impl_EnsureNotDisposed()
+void 
DynamicResultSetWrapper::impl_EnsureNotDisposed(std::unique_lock<std::mutex>& 
/*rGuard*/)
 {
-    std::unique_lock aGuard( m_aMutex );
     if( m_bDisposed )
         throw DisposedException();
 }
 
 //virtual
-void DynamicResultSetWrapper::impl_InitResultSetOne( const Reference< 
XResultSet >& xResultSet )
+void DynamicResultSetWrapper::impl_InitResultSetOne( 
std::unique_lock<std::mutex>& /*rGuard*/, const Reference< XResultSet >& 
xResultSet )
 {
-    std::unique_lock aGuard( m_aMutex );
     OSL_ENSURE( !m_xSourceResultOne.is(), "Source ResultSet One is set 
already" );
     m_xSourceResultOne = xResultSet;
     m_xMyResultOne = xResultSet;
 }
 
 //virtual
-void DynamicResultSetWrapper::impl_InitResultSetTwo( const Reference< 
XResultSet >& xResultSet )
+void DynamicResultSetWrapper::impl_InitResultSetTwo( 
std::unique_lock<std::mutex>& /*rGuard*/, const Reference< XResultSet >& 
xResultSet )
 {
-    std::unique_lock aGuard( m_aMutex );
     OSL_ENSURE( !m_xSourceResultTwo.is(), "Source ResultSet Two is set 
already" );
     m_xSourceResultTwo = xResultSet;
     m_xMyResultTwo = xResultSet;
@@ -123,9 +120,9 @@ css::uno::Any SAL_CALL 
DynamicResultSetWrapper::queryInterface( const css::uno::
 // virtual
 void SAL_CALL DynamicResultSetWrapper::dispose()
 {
-    impl_EnsureNotDisposed();
-
     std::unique_lock aGuard( m_aMutex );
+    impl_EnsureNotDisposed(aGuard);
+
     Reference< XComponent > xSourceComponent;
     if( m_bInDispose || m_bDisposed )
         return;
@@ -153,8 +150,8 @@ void SAL_CALL DynamicResultSetWrapper::dispose()
 // virtual
 void SAL_CALL DynamicResultSetWrapper::addEventListener( const Reference< 
XEventListener >& Listener )
 {
-    impl_EnsureNotDisposed();
     std::unique_lock aGuard( m_aMutex );
+    impl_EnsureNotDisposed(aGuard);
 
     m_aDisposeEventListeners.addInterface( aGuard, Listener );
 }
@@ -163,8 +160,8 @@ void SAL_CALL DynamicResultSetWrapper::addEventListener( 
const Reference< XEvent
 // virtual
 void SAL_CALL DynamicResultSetWrapper::removeEventListener( const Reference< 
XEventListener >& Listener )
 {
-    impl_EnsureNotDisposed();
     std::unique_lock aGuard( m_aMutex );
+    impl_EnsureNotDisposed(aGuard);
 
     m_aDisposeEventListeners.removeInterface( aGuard, Listener );
 }
@@ -176,10 +173,10 @@ void SAL_CALL 
DynamicResultSetWrapper::removeEventListener( const Reference< XEv
 //virtual
 void DynamicResultSetWrapper::impl_disposing( const EventObject& )
 {
-    impl_EnsureNotDisposed();
-
     std::unique_lock aGuard( m_aMutex );
 
+    impl_EnsureNotDisposed(aGuard);
+
     if( !m_xSource.is() )
         return;
 
@@ -194,7 +191,8 @@ void DynamicResultSetWrapper::impl_disposing( const 
EventObject& )
 //virtual
 void DynamicResultSetWrapper::impl_notify( const ListEvent& Changes )
 {
-    impl_EnsureNotDisposed();
+    std::unique_lock aGuard( m_aMutex );
+    impl_EnsureNotDisposed(aGuard);
     //@todo
     /*
     <p>The Listener is allowed to blockade this call, until he really want to 
go
@@ -208,40 +206,39 @@ void DynamicResultSetWrapper::impl_notify( const 
ListEvent& Changes )
     aNewEvent.Source = static_cast< XDynamicResultSet * >( this );
     aNewEvent.Changes = Changes.Changes;
 
+    for( ListAction& rAction : asNonConstRange(aNewEvent.Changes) )
     {
-        std::unique_lock aGuard( m_aMutex );
-        for( ListAction& rAction : asNonConstRange(aNewEvent.Changes) )
-        {
-            if (m_bGotWelcome)
-                break;
+        if (m_bGotWelcome)
+            break;
 
-            switch( rAction.ListActionType )
+        switch( rAction.ListActionType )
+        {
+            case ListActionType::WELCOME:
             {
-                case ListActionType::WELCOME:
+                WelcomeDynamicResultSetStruct aWelcome;
+                if( rAction.ActionInfo >>= aWelcome )
+                {
+                    impl_InitResultSetOne( aGuard, aWelcome.Old );
+                    impl_InitResultSetTwo( aGuard, aWelcome.New );
+                    m_bGotWelcome = true;
+
+                    aWelcome.Old = m_xMyResultOne;
+                    aWelcome.New = m_xMyResultTwo;
+
+                    rAction.ActionInfo <<= aWelcome;
+                }
+                else
                 {
-                    WelcomeDynamicResultSetStruct aWelcome;
-                    if( rAction.ActionInfo >>= aWelcome )
-                    {
-                        impl_InitResultSetOne( aWelcome.Old );
-                        impl_InitResultSetTwo( aWelcome.New );
-                        m_bGotWelcome = true;
-
-                        aWelcome.Old = m_xMyResultOne;
-                        aWelcome.New = m_xMyResultTwo;
-
-                        rAction.ActionInfo <<= aWelcome;
-                    }
-                    else
-                    {
-                        OSL_FAIL( "ListActionType was WELCOME but ActionInfo 
didn't contain a WelcomeDynamicResultSetStruct" );
-                        //throw RuntimeException();
-                    }
-                    break;
+                    OSL_FAIL( "ListActionType was WELCOME but ActionInfo 
didn't contain a WelcomeDynamicResultSetStruct" );
+                    //throw RuntimeException();
                 }
+                break;
             }
         }
-        OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
     }
+    OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
+
+    aGuard.unlock();
 
     if( !m_xListener.is() )
         m_aListenerSet.wait();
@@ -262,14 +259,10 @@ void DynamicResultSetWrapper::impl_notify( const 
ListEvent& Changes )
 //virtual
 void SAL_CALL DynamicResultSetWrapper::setSource( const Reference< XInterface 
> & Source )
 {
-    impl_EnsureNotDisposed();
-    {
-        std::unique_lock aGuard( m_aMutex );
-        if( m_xSource.is() )
-        {
-            throw AlreadyInitializedException();
-        }
-    }
+    std::unique_lock aGuard( m_aMutex );
+    impl_EnsureNotDisposed(aGuard);
+    if( m_xSource.is() )
+        throw AlreadyInitializedException();
 
     Reference< XDynamicResultSet > xSourceDynamic( Source, UNO_QUERY );
     OSL_ENSURE( xSourceDynamic.is(),
@@ -279,13 +272,10 @@ void SAL_CALL DynamicResultSetWrapper::setSource( const 
Reference< XInterface >
     Reference< XDynamicResultSetListener > xMyListenerImpl;
 
     bool bStatic = false;
-    {
-        std::unique_lock aGuard( m_aMutex );
-        m_xSource = xSourceDynamic;
-        xListener = m_xListener;
-        bStatic = m_bStatic;
-        xMyListenerImpl = m_xMyListenerImpl.get();
-    }
+    m_xSource = xSourceDynamic;
+    xListener = m_xListener;
+    bStatic = m_bStatic;
+    xMyListenerImpl = m_xMyListenerImpl.get();
     if( xListener.is() )
         xSourceDynamic->setListener( m_xMyListenerImpl );
     else if( bStatic )
@@ -302,19 +292,17 @@ void SAL_CALL DynamicResultSetWrapper::setSource( const 
Reference< XInterface >
 //virtual
 Reference< XResultSet > SAL_CALL DynamicResultSetWrapper::getStaticResultSet()
 {
-    impl_EnsureNotDisposed();
+    std::unique_lock aGuard( m_aMutex );
+    impl_EnsureNotDisposed(aGuard);
 
-    Reference< XDynamicResultSet > xSource;
-    Reference< XEventListener > xMyListenerImpl;
-    {
-        std::unique_lock aGuard( m_aMutex );
-        if( m_xListener.is() )
-            throw ListenerAlreadySetException();
+    if( m_xListener.is() )
+        throw ListenerAlreadySetException();
 
-        xSource = m_xSource;
-        m_bStatic = true;
-        xMyListenerImpl = m_xMyListenerImpl.get();
-    }
+    Reference< XDynamicResultSet > xSource = m_xSource;
+    Reference< XEventListener > xMyListenerImpl = m_xMyListenerImpl;
+    m_bStatic = true;
+
+    aGuard.unlock();
 
     if( xSource.is() )
     {
@@ -323,32 +311,32 @@ Reference< XResultSet > SAL_CALL 
DynamicResultSetWrapper::getStaticResultSet()
     if( !xSource.is() )
         m_aSourceSet.wait();
 
+    aGuard.lock();
 
     Reference< XResultSet > xResultSet = xSource->getStaticResultSet();
-    impl_InitResultSetOne( xResultSet );
+    impl_InitResultSetOne( aGuard, xResultSet );
     return m_xMyResultOne;
 }
 
 //virtual
 void SAL_CALL DynamicResultSetWrapper::setListener( const Reference< 
XDynamicResultSetListener > & Listener )
 {
-    impl_EnsureNotDisposed();
+    std::unique_lock aGuard( m_aMutex );
+    impl_EnsureNotDisposed(aGuard);
 
-    Reference< XDynamicResultSet > xSource;
-    Reference< XDynamicResultSetListener > xMyListenerImpl;
-    {
-        std::unique_lock aGuard( m_aMutex );
-        if( m_xListener.is() )
-            throw ListenerAlreadySetException();
-        if( m_bStatic )
-            throw ListenerAlreadySetException();
+    if( m_xListener.is() )
+        throw ListenerAlreadySetException();
+    if( m_bStatic )
+        throw ListenerAlreadySetException();
 
-        m_xListener = Listener;
-        addEventListener( Listener );
+    m_xListener = Listener;
+    m_aDisposeEventListeners.addInterface( aGuard, Listener );
+
+    Reference< XDynamicResultSet > xSource = m_xSource;
+    Reference< XDynamicResultSetListener > xMyListenerImpl = m_xMyListenerImpl;
+
+    aGuard.unlock();
 
-        xSource = m_xSource;
-        xMyListenerImpl = m_xMyListenerImpl.get();
-    }
     if ( xSource.is() )
         xSource->setListener( xMyListenerImpl );
 
@@ -358,12 +346,14 @@ void SAL_CALL DynamicResultSetWrapper::setListener( const 
Reference< XDynamicRes
 //virtual
 void SAL_CALL DynamicResultSetWrapper::connectToCache( const Reference< 
XDynamicResultSet > & xCache )
 {
-    impl_EnsureNotDisposed();
+    std::unique_lock aGuard( m_aMutex );
+    impl_EnsureNotDisposed(aGuard);
 
     if( m_xListener.is() )
         throw ListenerAlreadySetException();
     if( m_bStatic )
         throw ListenerAlreadySetException();
+    aGuard.unlock();
 
     Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
     OSL_ENSURE( xTarget.is(), "The given Target doesn't have the required 
interface 'XSourceInitialization'" );
@@ -394,8 +384,10 @@ void SAL_CALL DynamicResultSetWrapper::connectToCache( 
const Reference< XDynamic
 //virtual
 sal_Int16 SAL_CALL DynamicResultSetWrapper::getCapabilities()
 {
-    impl_EnsureNotDisposed();
-
+    {
+        std::unique_lock aGuard( m_aMutex );
+        impl_EnsureNotDisposed(aGuard);
+    }
     m_aSourceSet.wait();
     Reference< XDynamicResultSet > xSource;
     {
diff --git a/ucb/source/cacher/dynamicresultsetwrapper.hxx 
b/ucb/source/cacher/dynamicresultsetwrapper.hxx
index a7917506d874..ce4438b5cb43 100644
--- a/ucb/source/cacher/dynamicresultsetwrapper.hxx
+++ b/ucb/source/cacher/dynamicresultsetwrapper.hxx
@@ -79,13 +79,13 @@ protected:
     /// @throws css::lang::DisposedException
     /// @throws css::uno::RuntimeException
     void
-    impl_EnsureNotDisposed();
+    impl_EnsureNotDisposed(std::unique_lock<std::mutex>& rGuard);
 
     virtual void
-    impl_InitResultSetOne( const css::uno::Reference<
+    impl_InitResultSetOne( std::unique_lock<std::mutex>& rGuard, const 
css::uno::Reference<
                 css::sdbc::XResultSet >& xResultSet );
     virtual void
-    impl_InitResultSetTwo( const css::uno::Reference<
+    impl_InitResultSetTwo( std::unique_lock<std::mutex>& rGuard, const 
css::uno::Reference<
                 css::sdbc::XResultSet >& xResultSet );
 
 public:

Reply via email to