tdf#129930: Dispose SystemClipboard service early enough

At least on Windows, the related
CMtaOleClipboard::m_hClipboardChangedNotifierThread thread would otherwise still
run during cppuhelper::ServiceManager::disposing (but could try to create other
UNO services, which then throws a DeploymentException).

(There is also a GetSystemPrimarySelection similar to GetSystemClipboard in
include/vcl/transfer.hxx, which might or might not turn out to have a similar
issue.)

Change-Id: Ia64e708cf0578e3a127c1a56fbace577ecf4ee1f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86558
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
Stephan Bergmann 2020-01-10 17:23:44 +01:00
parent 76a8746ea4
commit 974ea67a7c
3 changed files with 38 additions and 0 deletions

View file

@ -102,6 +102,8 @@ class UITestLogger;
#define SV_ICON_ID_DATABASE 12 #define SV_ICON_ID_DATABASE 12
#define SV_ICON_ID_FORMULA 13 #define SV_ICON_ID_FORMULA 13
namespace com::sun::star::datatransfer::clipboard { class XClipboard; }
namespace vcl namespace vcl
{ {
class DisplayConnectionDispatch; class DisplayConnectionDispatch;
@ -372,6 +374,10 @@ struct ImplSVData
css::uno::Reference<css::i18n::XCharacterClassification> m_xCharClass; css::uno::Reference<css::i18n::XCharacterClassification> m_xCharClass;
#if defined _WIN32
css::uno::Reference<css::datatransfer::clipboard::XClipboard> m_xSystemClipboard;
#endif
Link<LinkParamNone*,void> maDeInitHook; Link<LinkParamNone*,void> maDeInitHook;
// LOK & headless backend specific hooks // LOK & headless backend specific hooks

View file

@ -484,6 +484,15 @@ void DeInitVCL()
pSVData->maCtrlData.mpDisclosureMinus.reset(); pSVData->maCtrlData.mpDisclosureMinus.reset();
pSVData->mpDefaultWin.disposeAndClear(); pSVData->mpDefaultWin.disposeAndClear();
#if defined _WIN32
// See GetSystemClipboard (vcl/source/treelist/transfer2.cxx):
if (auto const comp = css::uno::Reference<css::lang::XComponent>(
pSVData->m_xSystemClipboard, css::uno::UNO_QUERY))
{
comp->dispose();
}
#endif
#ifndef NDEBUG #ifndef NDEBUG
DbgGUIDeInitSolarMutexCheck(); DbgGUIDeInitSolarMutexCheck();
#endif #endif

View file

@ -21,6 +21,7 @@
#include <osl/mutex.hxx> #include <osl/mutex.hxx>
#include <sot/exchange.hxx> #include <sot/exchange.hxx>
#include <tools/debug.hxx>
#include <vcl/svapp.hxx> #include <vcl/svapp.hxx>
#include <vcl/window.hxx> #include <vcl/window.hxx>
#include <comphelper/processfactory.hxx> #include <comphelper/processfactory.hxx>
@ -32,6 +33,7 @@
#include <svl/urlbmk.hxx> #include <svl/urlbmk.hxx>
#include <vcl/transfer.hxx> #include <vcl/transfer.hxx>
#include <svdata.hxx>
using namespace ::com::sun::star::uno; using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang; using namespace ::com::sun::star::lang;
@ -462,6 +464,26 @@ void TransferDataContainer::DragFinished( sal_Int8 nDropAction )
Reference<XClipboard> GetSystemClipboard() Reference<XClipboard> GetSystemClipboard()
{ {
// On Windows, the css.datatransfer.clipboard.SystemClipboard UNO service is implemented as a
// single-instance service (sysdtrans_component_getFactory,
// dtrans/source/win32/clipb/wcbentry.cxx) that needs timely disposing to join a spawned thread
// (done in DeInitVCL, vcl/source/app/svmain.cxx), while on other platforms it is implemented as
// a mutli-instance service (ClipboardFactory, vcl/source/components/dtranscomp.cxx) so we
// should not hold on to a single instance here:
#if defined _WIN32
DBG_TESTSOLARMUTEX();
auto const data = ImplGetSVData();
if (!data->m_xSystemClipboard.is())
{
try
{
data->m_xSystemClipboard = css::datatransfer::clipboard::SystemClipboard::create(
comphelper::getProcessComponentContext());
}
catch (DeploymentException const &) {}
}
return data->m_xSystemClipboard;
#else
Reference<XClipboard> xClipboard; Reference<XClipboard> xClipboard;
try try
{ {
@ -470,6 +492,7 @@ Reference<XClipboard> GetSystemClipboard()
} }
catch (DeploymentException const &) {} catch (DeploymentException const &) {}
return xClipboard; return xClipboard;
#endif
} }
Reference<XClipboard> GetSystemPrimarySelection() Reference<XClipboard> GetSystemPrimarySelection()