[Libreoffice-commits] core.git: 4 commits - extensions/source framework/inc framework/source svx/source vcl/source vcl/unx
Caolán McNamara
caolanm at redhat.com
Wed Jun 22 10:34:26 UTC 2016
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 <caolanm at 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 <caolanm at 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 <caolanm at 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 <tml at 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 <caolanm at 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;
More information about the Libreoffice-commits
mailing list