tdf#121143: don't send OnCloseApp twice; properly cleanup AppBasicManager

The OnCloseApp event is being sent twice: first time in
SfxTerminateListener_Impl::notifyTermination (in Desktop::terminate),
and the second time in Desktop::doShutdown. The second event happens
after application's Basic manager already was destroyed in
SfxApplication::Deinitialize. The Basic provider, which holds a pointer
to the manager, doesn't properly cleanup upon the manager's destruction,
thus trying to use it after free.

This removes the second (duplicate) generated OnCloseApp event, and
makes BasicProviderImpl inherit from SfxListener to allow receiving the
manager's SfxHintId::Dying notification.

Change-Id: Iabf1432c41b1925b11b5a89e5fd8a6ae8249831e
Reviewed-on: https://gerrit.libreoffice.org/62810
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
This commit is contained in:
Mike Kaganski 2018-11-03 16:48:49 +03:00
parent a30dbe34a1
commit ba796f2cdd
3 changed files with 21 additions and 8 deletions

View file

@ -1686,13 +1686,6 @@ int Desktop::doShutdown()
if ( pExecGlobals->bRestartRequested )
SetRestartState();
if (pExecGlobals->xGlobalBroadcaster.is())
{
css::document::DocumentEvent aEvent;
aEvent.EventName = "OnCloseApp";
pExecGlobals->xGlobalBroadcaster->documentEventOccured(aEvent);
}
// Restore old value
const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
if ( rCmdLineArgs.IsHeadless() || rCmdLineArgs.IsEventTesting() )

View file

@ -158,6 +158,17 @@ namespace basprov
return bIsShared;
}
// SfxListener
void BasicProviderImpl::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
{
if (auto pManager = dynamic_cast<const BasicManager*>(&rBC))
if (pManager == m_pAppBasicManager && rHint.GetId() == SfxHintId::Dying)
{
EndListening(*m_pAppBasicManager);
m_pAppBasicManager = nullptr;
}
}
// XServiceInfo
OUString BasicProviderImpl::getImplementationName( )
{
@ -258,7 +269,11 @@ namespace basprov
// TODO
if ( !m_pAppBasicManager )
{
m_pAppBasicManager = SfxApplication::GetBasicManager();
if (m_pAppBasicManager)
StartListening(*m_pAppBasicManager);
}
if ( !m_xLibContainerApp.is() )
m_xLibContainerApp.set( SfxGetpApp()->GetBasicContainer(), UNO_QUERY );

View file

@ -29,6 +29,7 @@
#include <com/sun/star/document/XScriptInvocationContext.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <cppuhelper/implbase.hxx>
#include <svl/lstner.hxx>
class BasicManager;
@ -47,7 +48,7 @@ namespace basprov
css::script::browse::XBrowseNode > BasicProviderImpl_BASE;
class BasicProviderImpl : public BasicProviderImpl_BASE
class BasicProviderImpl : public BasicProviderImpl_BASE, public SfxListener
{
private:
BasicManager* m_pAppBasicManager;
@ -86,6 +87,10 @@ namespace basprov
virtual css::uno::Sequence< css::uno::Reference< css::script::browse::XBrowseNode > > SAL_CALL getChildNodes( ) override;
virtual sal_Bool SAL_CALL hasChildNodes( ) override;
virtual sal_Int16 SAL_CALL getType( ) override;
protected:
// SfxListener
virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
};