extensions/source/update/check/updatecheckjob.cxx | 16 +- framework/inc/services/desktop.hxx | 12 ++ framework/source/services/desktop.cxx | 23 ++++ svx/source/form/fmscriptingenv.cxx | 118 +++++++++++++++++++++- vcl/source/gdi/bitmap3.cxx | 3 vcl/unx/gtk/glomenu.cxx | 4 6 files changed, 166 insertions(+), 10 deletions(-)
New commits: commit 2822d1891b551a58c691cac37c11d3b9c2255755 Author: Caolán McNamara <caol...@redhat.com> Date: Wed Jun 22 11:31:23 2016 +0100 valgrind: use after free sal/osl/unx/conditn.cxx:90: pthread_cond_destroy failed: Device or resource busy sal/osl/unx/conditn.cxx:92: pthread_mutex_destroy failed: Device or resource busy "Desktop disposed before terminating it" seen under valgrind with CppunitTest_sccomp_lpsolver Change-Id: I643cf114b902c38a6a54487fd78c55d84ed78cfc diff --git a/extensions/source/update/check/updatecheckjob.cxx b/extensions/source/update/check/updatecheckjob.cxx index ba41067..5d48471 100644 --- a/extensions/source/update/check/updatecheckjob.cxx +++ b/extensions/source/update/check/updatecheckjob.cxx @@ -106,9 +106,9 @@ private: std::unique_ptr< InitUpdateCheckJobThread > m_pInitThread; void handleExtensionUpdates( const uno::Sequence< beans::NamedValue > &rListProp ); + void terminateAndJoinThread(); }; - InitUpdateCheckJobThread::InitUpdateCheckJobThread( const uno::Reference< uno::XComponentContext > &xContext, const uno::Sequence< beans::NamedValue > &xParameters, @@ -155,7 +155,6 @@ UpdateCheckJob::~UpdateCheckJob() { } - uno::Sequence< OUString > UpdateCheckJob::getServiceNames() { @@ -281,6 +280,7 @@ void SAL_CALL UpdateCheckJob::disposing( lang::EventObject const & rEvt ) if ( shutDown && m_xDesktop.is() ) { + terminateAndJoinThread(); m_xDesktop->removeTerminateListener( this ); m_xDesktop.clear(); } @@ -293,19 +293,23 @@ void SAL_CALL UpdateCheckJob::queryTermination( lang::EventObject const & ) { } - -void SAL_CALL UpdateCheckJob::notifyTermination( lang::EventObject const & ) - throw ( uno::RuntimeException, std::exception ) +void UpdateCheckJob::terminateAndJoinThread() { if ( m_pInitThread.get() != nullptr ) { m_pInitThread->setTerminating(); m_pInitThread->join(); + m_pInitThread.reset(); } } -} // anonymous namespace +void SAL_CALL UpdateCheckJob::notifyTermination( lang::EventObject const & ) + throw ( uno::RuntimeException, std::exception ) +{ + terminateAndJoinThread(); +} +} // anonymous namespace static uno::Reference<uno::XInterface> SAL_CALL createJobInstance(const uno::Reference<uno::XComponentContext>& xContext) commit 8488b3ba00e23e8ae6e089f450965c93c7a13d26 Author: Caolán McNamara <caol...@redhat.com> Date: Wed Jun 22 11:00:42 2016 +0100 G_MENU_ATTRIBUTE_ICON is only in glib >= 2.38 Change-Id: I7761ac05fbc9be39a6982ba66054c75a331816be diff --git a/vcl/unx/gtk/glomenu.cxx b/vcl/unx/gtk/glomenu.cxx index aab6857..f91a469 100644 --- a/vcl/unx/gtk/glomenu.cxx +++ b/vcl/unx/gtk/glomenu.cxx @@ -248,6 +248,10 @@ g_lo_menu_set_icon (GLOMenu *menu, else value = nullptr; +#ifndef G_MENU_ATTRIBUTE_ICON +# define G_MENU_ATTRIBUTE_ICON "icon" +#endif + g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_ICON, value); } commit 911c4d8472303053c19b14457a533d8b2f0a2ea9 Author: Caolán McNamara <caol...@redhat.com> Date: Wed Jun 22 10:55:24 2016 +0100 crashtesting: assert on export of tdf96006-1.odt to rtf revealed since... commit 81e3ca4f60e6ac0823c1233841c22a759cfe937f Author: Tor Lillqvist <t...@collabora.com> Date: Tue Jun 21 10:34:21 2016 +0300 surely here we should ask the palette how many entries are in it, not assume from the original bitcount that all entries exist. presumably the palette can only have <= 1 << BitCount entries in it Change-Id: Ieb1b98f2f13f702a6a6a20d8cf3d8e9a695141b2 diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx index c5de584..98ede14 100644 --- a/vcl/source/gdi/bitmap3.cxx +++ b/vcl/source/gdi/bitmap3.cxx @@ -623,8 +623,9 @@ bool Bitmap::ImplConvertUp(sal_uInt16 nBitCount, Color* pExtColor) if (pWriteAcc->HasPalette()) { - const sal_uInt16 nOldCount = 1 << GetBitCount(); const BitmapPalette& rOldPalette = pReadAcc->GetPalette(); + const sal_uInt16 nOldCount = rOldPalette.GetEntryCount(); + assert(nOldCount <= (1 << GetBitCount())); aPalette.SetEntryCount(1 << nBitCount); commit 68cf256f506d4601a2d2cf3ec2d56713afd491e6 Author: Caolán McNamara <caol...@redhat.com> Date: Tue Jun 21 21:29:25 2016 +0100 Resolves: tdf#88985 block app from exiting during macro execution but stop basic execution on the exit attempt, and then resend exit at a safe place when basic execution has stopped Change-Id: I77c43acffa0b82e8125dcb3b10ad9bf0d6dd26c3 diff --git a/framework/inc/services/desktop.hxx b/framework/inc/services/desktop.hxx index e8fd001..6e0c215 100644 --- a/framework/inc/services/desktop.hxx +++ b/framework/inc/services/desktop.hxx @@ -428,6 +428,18 @@ class Desktop : private cppu::BaseMutex, */ css::uno::Reference< css::frame::XTerminateListener > m_xQuickLauncher; + /** special terminate listener active when a macro is executing. + * Because basic runs Application::Yield internally the application may quit + * while running inside the internal basic event loop. So all the basic + * infrastructure may be deleted while the call is executing, leading to + * a varient of crashes. So this special terminate listener will + * veto the current quit attempt, stop basic execution, which will + * cause the inner event loop to quit, and on return to the outer normal + * application event loop then resend the quit attempt. + * So these implementation must be a special terminate listener too .-( + */ + css::uno::Reference< css::frame::XTerminateListener > m_xStarBasicQuitGuard; + /** special terminate listener which loads images asynchronous for current open documents. * Because internally it uses blocking system APIs... it can't be guaranteed that * running jobs can be cancelled successfully if the corresponding document will be closed... diff --git a/framework/source/services/desktop.cxx b/framework/source/services/desktop.cxx index 64e7e64..0ec0bce 100644 --- a/framework/source/services/desktop.cxx +++ b/framework/source/services/desktop.cxx @@ -171,6 +171,7 @@ Desktop::Desktop( const css::uno::Reference< css::uno::XComponentContext >& xCon , m_xDispatchRecorderSupplier( ) , m_xPipeTerminator ( ) , m_xQuickLauncher ( ) + , m_xStarBasicQuitGuard ( ) , m_xSWThreadManager ( ) , m_xSfxTerminator ( ) , m_xTitleNumberGenerator ( ) @@ -214,6 +215,7 @@ sal_Bool SAL_CALL Desktop::terminate() css::uno::Reference< css::frame::XTerminateListener > xPipeTerminator = m_xPipeTerminator; css::uno::Reference< css::frame::XTerminateListener > xQuickLauncher = m_xQuickLauncher; + css::uno::Reference< css::frame::XTerminateListener > xStarBasicQuitGuard = m_xStarBasicQuitGuard; css::uno::Reference< css::frame::XTerminateListener > xSWThreadManager = m_xSWThreadManager; css::uno::Reference< css::frame::XTerminateListener > xSfxTerminator = m_xSfxTerminator; @@ -275,6 +277,12 @@ sal_Bool SAL_CALL Desktop::terminate() lCalledTerminationListener.push_back( xQuickLauncher ); } + if ( xStarBasicQuitGuard.is() ) + { + xStarBasicQuitGuard->queryTermination( aEvent ); + lCalledTerminationListener.push_back( xStarBasicQuitGuard ); + } + if ( xSWThreadManager.is() ) { xSWThreadManager->queryTermination( aEvent ); @@ -322,6 +330,9 @@ sal_Bool SAL_CALL Desktop::terminate() xQuickLauncher->notifyTermination( aEvent ); } + if ( xStarBasicQuitGuard.is() ) + xStarBasicQuitGuard->notifyTermination( aEvent ); + if ( xSWThreadManager.is() ) xSWThreadManager->notifyTermination( aEvent ); @@ -395,6 +406,11 @@ void SAL_CALL Desktop::addTerminateListener( const css::uno::Reference< css::fra m_xQuickLauncher = xListener; return; } + if( sImplementationName == "com.sun.star.comp.svx.StarBasicQuitGuard" ) + { + m_xStarBasicQuitGuard = xListener; + return; + } if( sImplementationName == "com.sun.star.util.comp.FinalThreadManager" ) { m_xSWThreadManager = xListener; @@ -436,6 +452,12 @@ void SAL_CALL Desktop::removeTerminateListener( const css::uno::Reference< css:: return; } + if( sImplementationName == "com.sun.star.comp.svx.StarBasicQuitGuard" ) + { + m_xStarBasicQuitGuard.clear(); + return; + } + if( sImplementationName == "com.sun.star.util.comp.FinalThreadManager" ) { m_xSWThreadManager.clear(); @@ -1068,6 +1090,7 @@ void SAL_CALL Desktop::disposing() m_xPipeTerminator.clear(); m_xQuickLauncher.clear(); + m_xStarBasicQuitGuard.clear(); m_xSWThreadManager.clear(); m_xSfxTerminator.clear(); m_xCommandOptions.reset(); diff --git a/svx/source/form/fmscriptingenv.cxx b/svx/source/form/fmscriptingenv.cxx index 3cc284e..b79d421 100644 --- a/svx/source/form/fmscriptingenv.cxx +++ b/svx/source/form/fmscriptingenv.cxx @@ -22,14 +22,18 @@ #include "fmscriptingenv.hxx" #include "svx/fmmodel.hxx" -#include <com/sun/star/lang/IllegalArgumentException.hpp> -#include <com/sun/star/script/XScriptListener.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/frame/XTerminateListener.hpp> #include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/lang/EventObject.hpp> -#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/script/XScriptListener.hpp> #include <tools/diagnose_ex.h> #include <cppuhelper/implbase.hxx> +#include <cppuhelper/compbase.hxx> #include <comphelper/processfactory.hxx> #include <vcl/svapp.hxx> #include <osl/mutex.hxx> @@ -764,6 +768,111 @@ namespace svxform m_pScriptExecutor = nullptr; } + // tdf#88985 If LibreOffice tries to exit during the execution of a macro + // then: detect the effort, stop basic execution, block until the macro + // returns due to that stop, then restart the quit. This avoids the app + // exiting and destroying itself until the macro is parked at a safe place + // to do that. + class QuitGuard + { + private: + + class TerminateListener : public cppu::WeakComponentImplHelper<css::frame::XTerminateListener, + css::lang::XServiceInfo> + { + private: + css::uno::Reference<css::frame::XDesktop2> m_xDesktop; + osl::Mutex maMutex; + bool mbQuitBlocked; + public: + // XTerminateListener + virtual void SAL_CALL queryTermination(const css::lang::EventObject& /*rEvent*/) + throw(css::frame::TerminationVetoException, css::uno::RuntimeException, std::exception) override + { + mbQuitBlocked = true; + StarBASIC::Stop(); + throw css::frame::TerminationVetoException(); + } + + virtual void SAL_CALL notifyTermination(const css::lang::EventObject& /*rEvent*/) + throw(css::uno::RuntimeException, std::exception) override + { + mbQuitBlocked = false; + } + + using cppu::WeakComponentImplHelperBase::disposing; + + virtual void SAL_CALL disposing(const css::lang::EventObject& rEvent) + throw(css::uno::RuntimeException, std::exception) override + { + const bool bShutDown = (rEvent.Source == m_xDesktop); + if (bShutDown && m_xDesktop.is()) + { + m_xDesktop->removeTerminateListener(this); + m_xDesktop.clear(); + } + } + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() + throw (css::uno::RuntimeException, std::exception) override + { + return OUString("com.sun.star.comp.svx.StarBasicQuitGuard"); + } + + virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) + throw (css::uno::RuntimeException, std::exception) override + { + return cppu::supportsService(this, ServiceName); + } + + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() + throw (css::uno::RuntimeException, std::exception) override + { + css::uno::Sequence<OUString> aSeq { "com.sun.star.svx.StarBasicQuitGuard" }; + return aSeq; + } + + public: + TerminateListener() + : cppu::WeakComponentImplHelper<css::frame::XTerminateListener, + css::lang::XServiceInfo>(maMutex) + , mbQuitBlocked(false) + { + } + + void start() + { + css::uno::Reference<css::uno::XComponentContext> xContext(comphelper::getProcessComponentContext()); + m_xDesktop = css::frame::Desktop::create(xContext); + m_xDesktop->addTerminateListener(this); + } + + void stop() + { + if (!m_xDesktop.is()) + return; + m_xDesktop->removeTerminateListener(this); + if (mbQuitBlocked) + m_xDesktop->terminate(); + } + }; + + TerminateListener* mpListener; + css::uno::Reference<css::frame::XTerminateListener> mxLifeCycle; + public: + QuitGuard() + : mpListener(new TerminateListener) + , mxLifeCycle(mpListener) + { + mpListener->start(); + } + + ~QuitGuard() + { + mpListener->stop(); + } + }; IMPL_LINK_TYPED( FormScriptListener, OnAsyncScriptEvent, void*, p, void ) { @@ -776,7 +885,10 @@ namespace svxform ::osl::ClearableMutexGuard aGuard( m_aMutex ); if ( !impl_isDisposed_nothrow() ) + { + QuitGuard aQuitGuard; impl_doFireScriptEvent_nothrow( aGuard, *_pEvent, nullptr ); + } } delete _pEvent;
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits