From 6531640d6f05c9959168996c743c7248d560d6d2 Mon Sep 17 00:00:00 2001 From: Andreas Heinisch Date: Thu, 1 Oct 2026 21:51:27 +0200 Subject: [PATCH] tdf#125846 - Remove the terminate listener of an embedded object only once Otherwise, all remaining listeners will be checked, leading to performance issues when closing a document with many objects like formulas. Change-Id: I99b4b536e40af8a9045c7da6356cca87d3c88b02 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211697 Reviewed-by: Andreas Heinisch Tested-by: Jenkins --- embeddedobj/source/general/docholder.cxx | 12 ++++++++---- embeddedobj/source/inc/docholder.hxx | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/embeddedobj/source/general/docholder.cxx b/embeddedobj/source/general/docholder.cxx index 2b1d08b08d18..76eebd5bea7f 100644 --- a/embeddedobj/source/general/docholder.cxx +++ b/embeddedobj/source/general/docholder.cxx @@ -156,7 +156,7 @@ DocumentHolder::DocumentHolder( uno::Reference< uno::XComponentContext > xContex m_bReadOnly( false ), m_bWaitForClose( false ), m_bAllowClosing( false ), - m_bDesktopTerminated( false ), + m_bTerminateListenerRegistered( false ), m_nNoBorderResizeReact( 0 ), m_nNoResizeReact( 0 ) { @@ -165,6 +165,7 @@ DocumentHolder::DocumentHolder( uno::Reference< uno::XComponentContext > xContex try { xDesktop->addTerminateListener( this ); + m_bTerminateListenerRegistered = true; } catch ( const uno::Exception& ) { @@ -198,8 +199,7 @@ DocumentHolder::~DocumentHolder() m_xInterceptor.clear(); } - if ( !m_bDesktopTerminated ) - FreeOffice(); + FreeOffice(); } @@ -233,6 +233,10 @@ void DocumentHolder::CloseFrame() void DocumentHolder::FreeOffice() { + // tdf#125846 - deregister listener only once since a second removal would check all listeners + if (!m_bTerminateListenerRegistered) + return; + m_bTerminateListenerRegistered = false; try { uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext ); xDesktop->removeTerminateListener( this ); @@ -1152,8 +1156,8 @@ void SAL_CALL DocumentHolder::notifyTermination( const lang::EventObject& aSourc { OSL_ENSURE( !m_xComponent.is(), "Just a disaster..." ); + m_bTerminateListenerRegistered = false; uno::Reference< frame::XDesktop > xDesktop( aSource.Source, uno::UNO_QUERY ); - m_bDesktopTerminated = true; if ( xDesktop.is() ) xDesktop->removeTerminateListener( static_cast(this) ); } diff --git a/embeddedobj/source/inc/docholder.hxx b/embeddedobj/source/inc/docholder.hxx index 2c221cc411c6..21e915d09e32 100644 --- a/embeddedobj/source/inc/docholder.hxx +++ b/embeddedobj/source/inc/docholder.hxx @@ -77,7 +77,7 @@ private: bool m_bWaitForClose; bool m_bAllowClosing; - bool m_bDesktopTerminated; + bool m_bTerminateListenerRegistered; sal_Int32 m_nNoBorderResizeReact; sal_Int32 m_nNoResizeReact;