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: