diff --git a/embeddedobj/source/inc/oleembobj.hxx b/embeddedobj/source/inc/oleembobj.hxx index 62fea5d35702..28fe88b02b38 100644 --- a/embeddedobj/source/inc/oleembobj.hxx +++ b/embeddedobj/source/inc/oleembobj.hxx @@ -219,9 +219,9 @@ protected: #ifdef _WIN32 void SwitchComponentToRunningState_Impl(osl::ResettableMutexGuard& guard); #endif - void MakeEventListenerNotification_Impl( const OUString& aEventName ); + void MakeEventListenerNotification_Impl( const OUString& aEventName, osl::ResettableMutexGuard& guard ); #ifdef _WIN32 - void StateChangeNotification_Impl( bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState ); + void StateChangeNotification_Impl( bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState, osl::ResettableMutexGuard& guard ); css::uno::Reference< css::io::XOutputStream > GetStreamForSaving(); diff --git a/embeddedobj/source/msole/oleembed.cxx b/embeddedobj/source/msole/oleembed.cxx index f61d8056fdeb..09eac6e5e1b7 100644 --- a/embeddedobj/source/msole/oleembed.cxx +++ b/embeddedobj/source/msole/oleembed.cxx @@ -481,9 +481,7 @@ void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState ) // will behave after activation sal_Int32 nOldState = m_nObjectState; - aGuard.clear(); - StateChangeNotification_Impl( true, nOldState, nNewState ); - aGuard.reset(); + StateChangeNotification_Impl( true, nOldState, nNewState, aGuard ); try { @@ -498,14 +496,12 @@ void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState ) // the loaded state must be set before, because of notifications! m_nObjectState = nNewState; - aGuard.clear(); { VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController ); - m_pOleComponent->CloseObject(); + ExecUnlocked([p = m_pOleComponent] { p->CloseObject(); }, aGuard); } - StateChangeNotification_Impl( false, nOldState, m_nObjectState ); - aGuard.reset(); + StateChangeNotification_Impl( false, nOldState, m_nObjectState, aGuard ); } else if ( nNewState == embed::EmbedStates::RUNNING || nNewState == embed::EmbedStates::ACTIVE ) { @@ -520,19 +516,17 @@ void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState ) SwitchComponentToRunningState_Impl(aGuard); m_nObjectState = embed::EmbedStates::RUNNING; - aGuard.clear(); - StateChangeNotification_Impl( false, nOldState, m_nObjectState ); - aGuard.reset(); + StateChangeNotification_Impl( false, nOldState, m_nObjectState, aGuard ); if ( m_pOleComponent && m_bHasSizeToSet ) { - aGuard.clear(); try { - m_pOleComponent->SetExtent( m_aSizeToSet, m_nAspectToSet ); + ExecUnlocked([p = m_pOleComponent, s = m_aSizeToSet, + a = m_nAspectToSet]() { p->SetExtent(s, a); }, + aGuard); m_bHasSizeToSet = false; } catch( const uno::Exception& ) {} - aGuard.reset(); } if ( m_nObjectState == nNewState ) @@ -544,30 +538,33 @@ void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState ) if ( m_nObjectState == embed::EmbedStates::RUNNING && nNewState == embed::EmbedStates::ACTIVE ) { // execute OPEN verb, if object does not reach active state it is an object's problem - aGuard.clear(); - m_pOleComponent->ExecuteVerb( embed::EmbedVerbs::MS_OLEVERB_OPEN ); - aGuard.reset(); + ExecUnlocked([p = m_pOleComponent]() + { p->ExecuteVerb(embed::EmbedVerbs::MS_OLEVERB_OPEN); }, + aGuard); // some objects do not allow to set the size even in running state if ( m_pOleComponent && m_bHasSizeToSet ) { - aGuard.clear(); try { - m_pOleComponent->SetExtent( m_aSizeToSet, m_nAspectToSet ); + ExecUnlocked([p = m_pOleComponent, s = m_aSizeToSet, + a = m_nAspectToSet]() { p->SetExtent(s, a); }, + aGuard); m_bHasSizeToSet = false; } catch( uno::Exception& ) {} - aGuard.reset(); } m_nObjectState = nNewState; } else if ( m_nObjectState == embed::EmbedStates::ACTIVE && nNewState == embed::EmbedStates::RUNNING ) { - aGuard.clear(); - m_pOleComponent->CloseObject(); - m_pOleComponent->RunObject(); // Should not fail, the object already was active - aGuard.reset(); + ExecUnlocked( + [p = m_pOleComponent]() + { + p->CloseObject(); + p->RunObject(); // Should not fail, the object already was active + }, + aGuard); m_nObjectState = nNewState; } else @@ -580,8 +577,7 @@ void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState ) } catch( uno::Exception& ) { - aGuard.clear(); - StateChangeNotification_Impl( false, nOldState, m_nObjectState ); + StateChangeNotification_Impl( false, nOldState, m_nObjectState, aGuard ); throw; } } @@ -857,9 +853,7 @@ void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID ) { // if the target object is in loaded state // it must be switched to running state to execute verb - aGuard.clear(); - changeState( embed::EmbedStates::RUNNING ); - aGuard.reset(); + ExecUnlocked([this]() { changeState(embed::EmbedStates::RUNNING); }, aGuard); } try { @@ -869,11 +863,13 @@ void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID ) // ==== the STAMPIT related solution ============================= m_aVerbExecutionController.StartControlExecution(); - { - osl::ResettableMutexGuardScopedReleaser clearedMutex(aGuard); - m_pOleComponent->ExecuteVerb(nVerbID); - m_pOleComponent->SetHostName(m_aContainerName); - } + ExecUnlocked( + [nVerbID, p = m_pOleComponent, name = m_aContainerName]() + { + p->ExecuteVerb(nVerbID); + p->SetHostName(name); + }, + aGuard); // ==== the STAMPIT related solution ============================= bool bModifiedOnExecution = m_aVerbExecutionController.EndControlExecution_WasModified(); @@ -889,9 +885,7 @@ void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID ) // ==== the STAMPIT related solution ============================= m_aVerbExecutionController.EndControlExecution_WasModified(); - - aGuard.clear(); - StateChangeNotification_Impl( false, nOldState, m_nObjectState ); + StateChangeNotification_Impl( false, nOldState, m_nObjectState, aGuard ); throw; } @@ -1154,10 +1148,7 @@ sal_Int64 SAL_CALL OleEmbeddedObject::getStatus( sal_Int64 nResult = m_nStatus; else if ( m_pOleComponent ) { - { - osl::ResettableMutexGuardScopedReleaser clearedMutex(aGuard); - m_nStatus = m_pOleComponent->GetMiscStatus(nAspect); - } + m_nStatus = ExecUnlocked([p = m_pOleComponent, nAspect] { return p->GetMiscStatus(nAspect); }, aGuard); m_nStatusAspect = nAspect; m_bGotStatus = true; nResult = m_nStatus; diff --git a/embeddedobj/source/msole/olemisc.cxx b/embeddedobj/source/msole/olemisc.cxx index 582ae49de56f..e3159e99fd0f 100644 --- a/embeddedobj/source/msole/olemisc.cxx +++ b/embeddedobj/source/msole/olemisc.cxx @@ -154,7 +154,8 @@ OleEmbeddedObject::~OleEmbeddedObject() } -void OleEmbeddedObject::MakeEventListenerNotification_Impl( const OUString& aEventName ) +void OleEmbeddedObject::MakeEventListenerNotification_Impl( const OUString& aEventName, + osl::ResettableMutexGuard& guard ) { if ( !m_pInterfaceContainer ) return; @@ -165,59 +166,59 @@ void OleEmbeddedObject::MakeEventListenerNotification_Impl( const OUString& aEve if ( pContainer == nullptr ) return; - document::EventObject aEvent( static_cast< ::cppu::OWeakObject* >( this ), aEventName ); - comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer); - while (pIterator.hasMoreElements()) + auto proc = [&guard, aEvent = document::EventObject(getXWeak(), aEventName)]( + const uno::Reference& xListener) { try { - static_cast(pIterator.next())->notifyEvent( aEvent ); + osl::ResettableMutexGuardScopedReleaser area(guard); + xListener->notifyEvent(aEvent); } - catch( const uno::RuntimeException& ) + catch (const lang::DisposedException&) + { + throw; // forEach handles this + } + catch (const uno::RuntimeException&) { } - } + }; + pContainer->forEach(proc); } #ifdef _WIN32 -void OleEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState ) +void OleEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState, + osl::ResettableMutexGuard& guard ) { - if ( m_pInterfaceContainer ) - { - comphelper::OInterfaceContainerHelper2* pContainer = m_pInterfaceContainer->getContainer( - cppu::UnoType::get()); - if ( pContainer != nullptr ) - { - lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) ); - comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer); + if (!m_pInterfaceContainer) + return; - while (pIterator.hasMoreElements()) - { - if ( bBeforeChange ) - { - try - { - static_cast(pIterator.next())->changingState( aSource, nOldState, nNewState ); - } - catch( const uno::Exception& ) - { - // even if the listener complains ignore it for now - } - } - else - { - try - { - static_cast(pIterator.next())->stateChanged( aSource, nOldState, nNewState ); - } - catch( const uno::Exception& ) - { - // if anything happened it is problem of listener, ignore it - } - } - } + comphelper::OInterfaceContainerHelper2* pContainer = m_pInterfaceContainer->getContainer( + cppu::UnoType::get()); + if (!pContainer) + return; + + auto proc + = [bBeforeChange, nOldState, nNewState, &guard, aSource = lang::EventObject(getXWeak())]( + const uno::Reference& xListener) + { + try + { + osl::ResettableMutexGuardScopedReleaser area(guard); + if (bBeforeChange) + xListener->changingState(aSource, nOldState, nNewState); + else + xListener->stateChanged(aSource, nOldState, nNewState); } - } + catch (const lang::DisposedException&) + { + throw; // forEach handles this + } + catch (const uno::Exception&) + { + // even if the listener complains ignore it for now + } + }; + pContainer->forEach(proc); } #endif diff --git a/embeddedobj/source/msole/olepersist.cxx b/embeddedobj/source/msole/olepersist.cxx index 65811c31a331..1ddc02b27c8b 100644 --- a/embeddedobj/source/msole/olepersist.cxx +++ b/embeddedobj/source/msole/olepersist.cxx @@ -822,7 +822,7 @@ bool OleEmbeddedObject::SaveObject_Impl() bool OleEmbeddedObject::OnShowWindow_Impl( bool bShow ) { - osl::ClearableMutexGuard aGuard(m_aMutex); + osl::ResettableMutexGuard aGuard(m_aMutex); bool bResult = false; @@ -838,21 +838,19 @@ bool OleEmbeddedObject::OnShowWindow_Impl( bool bShow ) m_nObjectState = embed::EmbedStates::ACTIVE; m_aVerbExecutionController.ObjectIsActive(); - aGuard.clear(); - StateChangeNotification_Impl( false, nOldState, m_nObjectState ); + StateChangeNotification_Impl( false, nOldState, m_nObjectState, aGuard ); } else if ( !bShow && m_nObjectState == embed::EmbedStates::ACTIVE ) { m_nObjectState = embed::EmbedStates::RUNNING; - aGuard.clear(); - StateChangeNotification_Impl( false, nOldState, m_nObjectState ); + StateChangeNotification_Impl( false, nOldState, m_nObjectState, aGuard ); } if ( m_xClientSite.is() ) { try { - m_xClientSite->visibilityChanged( bShow ); + ExecUnlocked([p = m_xClientSite, bShow] { p->visibilityChanged(bShow); }, aGuard); bResult = true; } catch( const uno::Exception& ) @@ -873,6 +871,7 @@ void OleEmbeddedObject::OnIconChanged_Impl() void OleEmbeddedObject::OnViewChanged_Impl() { + osl::ResettableMutexGuard aGuard(m_aMutex); if ( m_bDisposed ) throw lang::DisposedException(); @@ -896,7 +895,7 @@ void OleEmbeddedObject::OnViewChanged_Impl() // The view is changed while the object is in running state, save the new object m_xCachedVisualRepresentation.clear(); SaveObject_Impl(); - MakeEventListenerNotification_Impl( "OnVisAreaChanged" ); + MakeEventListenerNotification_Impl( "OnVisAreaChanged", aGuard ); } } @@ -904,6 +903,7 @@ void OleEmbeddedObject::OnViewChanged_Impl() void OleEmbeddedObject::OnClosed_Impl() { + osl::ResettableMutexGuard aGuard(m_aMutex); if ( m_bDisposed ) throw lang::DisposedException(); @@ -911,7 +911,7 @@ void OleEmbeddedObject::OnClosed_Impl() { sal_Int32 nOldState = m_nObjectState; m_nObjectState = embed::EmbedStates::LOADED; - StateChangeNotification_Impl( false, nOldState, m_nObjectState ); + StateChangeNotification_Impl( false, nOldState, m_nObjectState, aGuard ); } } @@ -1114,7 +1114,7 @@ void OleEmbeddedObject::StoreToLocation_Impl( #ifdef _WIN32 // if the object was NOT modified after storing it can be just copied // as if it was in loaded state - || (m_pOleComponent && !ExecUnlocked([this] { return m_pOleComponent->IsDirty(); }, rGuard)) + || (m_pOleComponent && !ExecUnlocked([p = m_pOleComponent] { return p->IsDirty(); }, rGuard)) #endif ) { @@ -1537,7 +1537,7 @@ void SAL_CALL OleEmbeddedObject::saveCompleted( sal_Bool bUseNew ) } // end wrapping related part ==================== - osl::ClearableMutexGuard aGuard(m_aMutex); + osl::ResettableMutexGuard aGuard(m_aMutex); if ( m_bDisposed ) throw lang::DisposedException(); // TODO @@ -1606,16 +1606,15 @@ void SAL_CALL OleEmbeddedObject::saveCompleted( sal_Bool bUseNew ) {} } - aGuard.clear(); if ( bUseNew ) { - MakeEventListenerNotification_Impl( u"OnSaveAsDone"_ustr); + MakeEventListenerNotification_Impl( u"OnSaveAsDone"_ustr, aGuard); // the object can be changed only on windows // the notification should be done only if the object is not in loaded state if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded ) { - MakeEventListenerNotification_Impl( u"OnVisAreaChanged"_ustr); + MakeEventListenerNotification_Impl( u"OnVisAreaChanged"_ustr, aGuard); } } } @@ -1721,7 +1720,7 @@ void SAL_CALL OleEmbeddedObject::storeOwn() bool bStoreLoaded = true; #ifdef _WIN32 - if ( m_nObjectState != embed::EmbedStates::LOADED && m_pOleComponent && ExecUnlocked([this] { return m_pOleComponent->IsDirty(); }, aGuard) ) + if ( m_nObjectState != embed::EmbedStates::LOADED && m_pOleComponent && ExecUnlocked([p = m_pOleComponent] { return p->IsDirty(); }, aGuard) ) { bStoreLoaded = false; @@ -1782,14 +1781,12 @@ void SAL_CALL OleEmbeddedObject::storeOwn() {} } - aGuard.clear(); - - MakeEventListenerNotification_Impl( u"OnSaveDone"_ustr); + MakeEventListenerNotification_Impl( u"OnSaveDone"_ustr, aGuard); // the object can be changed only on Windows // the notification should be done only if the object is not in loaded state if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded ) - MakeEventListenerNotification_Impl( u"OnVisAreaChanged"_ustr); + MakeEventListenerNotification_Impl( u"OnVisAreaChanged"_ustr, aGuard); }