[Libreoffice-commits] core.git: sfx2/source
Noel Grandin (via logerrit)
logerrit at kemper.freedesktop.org
Tue Aug 24 12:43:59 UTC 2021
sfx2/source/notify/globalevents.cxx | 134 ++++++++++++++++++------------------
1 file changed, 68 insertions(+), 66 deletions(-)
New commits:
commit 8122c82d90117fc0c4c8ea87aa7f771d5e92bf36
Author: Noel Grandin <noelgrandin at gmail.com>
AuthorDate: Sun Aug 22 21:11:08 2021 +0200
Commit: Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Tue Aug 24 14:43:25 2021 +0200
osl::Mutex->std::mutex in SfxGlobalEvents_Impl
Change-Id: I4dae3225b961b663493ca4ea40b6bbec2439270f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120905
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
diff --git a/sfx2/source/notify/globalevents.cxx b/sfx2/source/notify/globalevents.cxx
index 2176c327243f..3982fbecdb33 100644
--- a/sfx2/source/notify/globalevents.cxx
+++ b/sfx2/source/notify/globalevents.cxx
@@ -32,7 +32,7 @@
#include <com/sun/star/uno/Type.hxx>
#include <cppuhelper/implbase.hxx>
-#include <comphelper/interfacecontainer2.hxx>
+#include <comphelper/interfacecontainer4.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <rtl/ref.hxx>
#include <comphelper/enumhelper.hxx>
@@ -41,6 +41,7 @@
#include <unotools/eventcfg.hxx>
#include <eventsupplier.hxx>
+#include <mutex>
#include <set>
#include <vector>
@@ -48,28 +49,22 @@ using namespace css;
namespace {
-struct ModelCollectionMutexBase
-{
-public:
- osl::Mutex m_aLock;
-};
-
typedef ::std::vector< css::uno::Reference< css::frame::XModel > > TModelList;
//TODO: remove support of obsolete document::XEventBroadcaster/Listener
-class SfxGlobalEvents_Impl : public ModelCollectionMutexBase
- , public ::cppu::WeakImplHelper< css::lang::XServiceInfo
+class SfxGlobalEvents_Impl : public ::cppu::WeakImplHelper< css::lang::XServiceInfo
, css::frame::XGlobalEventBroadcaster
, css::document::XEventBroadcaster
, css::document::XEventListener
, css::lang::XComponent
>
{
+ std::mutex m_aLock;
css::uno::Reference< css::container::XNameReplace > m_xEvents;
css::uno::Reference< css::document::XEventListener > m_xJobExecutorListener;
- ::comphelper::OInterfaceContainerHelper2 m_aLegacyListeners;
- ::comphelper::OInterfaceContainerHelper2 m_aDocumentListeners;
+ ::comphelper::OInterfaceContainerHelper4<document::XEventListener> m_aLegacyListeners;
+ ::comphelper::OInterfaceContainerHelper4<document::XDocumentEventListener> m_aDocumentListeners;
std::multiset<css::uno::Reference<css::lang::XEventListener>> m_disposeListeners;
TModelList m_lModels;
bool m_disposed;
@@ -150,10 +145,7 @@ private:
};
SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const uno::Reference < uno::XComponentContext >& rxContext)
- : ModelCollectionMutexBase( )
- , m_xJobExecutorListener( task::theJobExecutor::get( rxContext ), uno::UNO_QUERY_THROW )
- , m_aLegacyListeners (m_aLock)
- , m_aDocumentListeners (m_aLock)
+ : m_xJobExecutorListener( task::theJobExecutor::get( rxContext ), uno::UNO_QUERY_THROW )
, m_disposed(false)
{
osl_atomic_increment(&m_refCount);
@@ -165,7 +157,7 @@ SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const uno::Reference < uno::XCompone
uno::Reference< container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents()
{
// SAFE ->
- osl::MutexGuard aLock(m_aLock);
+ std::scoped_lock aLock(m_aLock);
if (m_disposed) {
throw css::lang::DisposedException();
}
@@ -176,55 +168,33 @@ uno::Reference< container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEven
void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const uno::Reference< document::XEventListener >& xListener)
{
- {
- osl::MutexGuard g(m_aLock);
- if (m_disposed) {
- throw css::lang::DisposedException();
- }
- }
- // container is threadsafe
+ std::scoped_lock g(m_aLock);
+ if (m_disposed)
+ throw css::lang::DisposedException();
m_aLegacyListeners.addInterface(xListener);
- // Take care of an XComponent::dispose being processed in parallel with the above addInterface:
- {
- osl::MutexGuard g(m_aLock);
- if (!m_disposed) {
- return;
- }
- }
- m_aLegacyListeners.disposeAndClear({static_cast<OWeakObject *>(this)});
}
void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const uno::Reference< document::XEventListener >& xListener)
{
- // The below removeInterface will silently do nothing when m_disposed:
- // container is threadsafe
+ std::scoped_lock g(m_aLock);
+ // The below removeInterface will silently do nothing when m_disposed
m_aLegacyListeners.removeInterface(xListener);
}
void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& Listener )
{
- {
- osl::MutexGuard g(m_aLock);
- if (m_disposed) {
- throw css::lang::DisposedException();
- }
- }
+ std::scoped_lock g(m_aLock);
+ if (m_disposed)
+ throw css::lang::DisposedException();
m_aDocumentListeners.addInterface( Listener );
- // Take care of an XComponent::dispose being processed in parallel with the above addInterface:
- {
- osl::MutexGuard g(m_aLock);
- if (!m_disposed) {
- return;
- }
- }
- m_aDocumentListeners.disposeAndClear({static_cast<OWeakObject *>(this)});
}
void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& Listener )
{
+ std::scoped_lock g(m_aLock);
// The below removeInterface will silently do nothing when m_disposed:
m_aDocumentListeners.removeInterface( Listener );
}
@@ -262,7 +232,7 @@ void SAL_CALL SfxGlobalEvents_Impl::disposing(const lang::EventObject& aEvent)
uno::Reference< frame::XModel > xDoc(aEvent.Source, uno::UNO_QUERY);
// SAFE ->
- osl::MutexGuard aLock(m_aLock);
+ std::scoped_lock g(m_aLock);
TModelList::iterator pIt = impl_searchDoc(xDoc);
if (pIt != m_lModels.end())
m_lModels.erase(pIt);
@@ -272,15 +242,16 @@ void SAL_CALL SfxGlobalEvents_Impl::disposing(const lang::EventObject& aEvent)
void SfxGlobalEvents_Impl::dispose() {
std::multiset<css::uno::Reference<css::lang::XEventListener>> listeners;
{
- osl::MutexGuard g(m_aLock);
+ std::unique_lock g(m_aLock);
m_xEvents.clear();
m_xJobExecutorListener.clear();
m_disposeListeners.swap(listeners);
m_lModels.clear();
m_disposed = true;
+ m_aLegacyListeners.disposeAndClear(g, {static_cast<OWeakObject *>(this)});
+ g.lock(); // because disposeAndClear is going to want to unlock()
+ m_aDocumentListeners.disposeAndClear(g, {static_cast<OWeakObject *>(this)});
}
- m_aLegacyListeners.disposeAndClear({static_cast<OWeakObject *>(this)});
- m_aDocumentListeners.disposeAndClear({static_cast<OWeakObject *>(this)});
for (auto const & i: listeners) {
try {
i->disposing({static_cast< cppu::OWeakObject * >(this)});
@@ -295,7 +266,7 @@ void SfxGlobalEvents_Impl::addEventListener(
throw css::uno::RuntimeException("null listener");
}
{
- osl::MutexGuard g(m_aLock);
+ std::scoped_lock g(m_aLock);
if (!m_disposed) {
m_disposeListeners.insert(xListener);
return;
@@ -309,7 +280,7 @@ void SfxGlobalEvents_Impl::addEventListener(
void SfxGlobalEvents_Impl::removeEventListener(
css::uno::Reference<css::lang::XEventListener> const & aListener)
{
- osl::MutexGuard g(m_aLock);
+ std::scoped_lock g(m_aLock);
auto const i = m_disposeListeners.find(aListener);
if (i != m_disposeListeners.end()) {
m_disposeListeners.erase(i);
@@ -324,7 +295,7 @@ sal_Bool SAL_CALL SfxGlobalEvents_Impl::has(const uno::Any& aElement)
bool bHas = false;
// SAFE ->
- osl::MutexGuard aLock(m_aLock);
+ std::scoped_lock g(m_aLock);
if (m_disposed) {
throw css::lang::DisposedException();
}
@@ -349,7 +320,7 @@ void SAL_CALL SfxGlobalEvents_Impl::insert( const uno::Any& aElement )
// SAFE ->
{
- osl::MutexGuard aLock(m_aLock);
+ std::scoped_lock g(m_aLock);
if (m_disposed) {
throw css::lang::DisposedException();
}
@@ -387,7 +358,7 @@ void SAL_CALL SfxGlobalEvents_Impl::remove( const uno::Any& aElement )
// SAFE ->
{
- osl::MutexGuard aLock(m_aLock);
+ std::scoped_lock g(m_aLock);
TModelList::iterator pIt = impl_searchDoc(xDoc);
if (pIt == m_lModels.end())
throw container::NoSuchElementException(
@@ -413,7 +384,7 @@ void SAL_CALL SfxGlobalEvents_Impl::remove( const uno::Any& aElement )
uno::Reference< container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration()
{
// SAFE ->
- osl::MutexGuard aLock(m_aLock);
+ std::scoped_lock g(m_aLock);
if (m_disposed) {
throw css::lang::DisposedException();
}
@@ -438,7 +409,7 @@ uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType()
sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements()
{
// SAFE ->
- osl::MutexGuard aLock(m_aLock);
+ std::scoped_lock g(m_aLock);
if (m_disposed) {
throw css::lang::DisposedException();
}
@@ -451,7 +422,7 @@ void SfxGlobalEvents_Impl::implts_notifyJobExecution(const document::EventObject
{
css::uno::Reference<css::document::XEventListener> listener;
{
- osl::MutexGuard g(m_aLock);
+ std::scoped_lock g(m_aLock);
listener = m_xJobExecutorListener;
}
if (!listener.is()) {
@@ -472,7 +443,7 @@ void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const document::D
{
css::uno::Reference<css::container::XNameReplace> events;
{
- osl::MutexGuard g(m_aLock);
+ std::scoped_lock g(m_aLock);
events = m_xEvents;
}
if (!events.is()) {
@@ -498,11 +469,43 @@ void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const document::D
void SfxGlobalEvents_Impl::implts_notifyListener(const document::DocumentEvent& aEvent)
{
- // containers are threadsafe
+ std::optional<comphelper::OInterfaceIteratorHelper4<document::XEventListener>> aIt1;
+ std::optional<comphelper::OInterfaceIteratorHelper4<document::XDocumentEventListener>> aIt2;
+
+ {
+ std::scoped_lock g(m_aLock);
+ aIt1.emplace(m_aLegacyListeners);
+ aIt2.emplace(m_aDocumentListeners);
+ }
+
document::EventObject aLegacyEvent(aEvent.Source, aEvent.EventName);
- m_aLegacyListeners.notifyEach( &document::XEventListener::notifyEvent, aLegacyEvent );
+ while (aIt1->hasMoreElements())
+ {
+ auto xListener = aIt1->next();
+ try
+ {
+ xListener->notifyEvent(aLegacyEvent);
+ }
+ catch (css::lang::DisposedException const& exc)
+ {
+ if (exc.Context == xListener)
+ aIt1->remove();
+ }
+ }
- m_aDocumentListeners.notifyEach( &document::XDocumentEventListener::documentEventOccured, aEvent );
+ while (aIt2->hasMoreElements())
+ {
+ auto xListener = aIt2->next();
+ try
+ {
+ xListener->documentEventOccured(aEvent);
+ }
+ catch (css::lang::DisposedException const& exc)
+ {
+ if (exc.Context == xListener)
+ aIt2->remove();
+ }
+ }
}
@@ -513,9 +516,8 @@ TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const uno::Reference<
return m_lModels.end();
return std::find_if(m_lModels.begin(), m_lModels.end(),
- [&xModel](const TModelList::value_type& rxModel) {
- uno::Reference< frame::XModel > xContainerDoc(rxModel, uno::UNO_QUERY);
- return xContainerDoc == xModel;
+ [&xModel](const uno::Reference< frame::XModel >& rxModel) {
+ return rxModel == xModel;
});
}
More information about the Libreoffice-commits
mailing list