From 974ea67a7c345a8be98c5aaa59baf9b07959b708 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Fri, 10 Jan 2020 17:23:44 +0100 Subject: [PATCH] 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 --- vcl/inc/svdata.hxx | 6 ++++++ vcl/source/app/svmain.cxx | 9 +++++++++ vcl/source/treelist/transfer2.cxx | 23 +++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx index a0def514557e..c91a6e4139ae 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -102,6 +102,8 @@ class UITestLogger; #define SV_ICON_ID_DATABASE 12 #define SV_ICON_ID_FORMULA 13 +namespace com::sun::star::datatransfer::clipboard { class XClipboard; } + namespace vcl { class DisplayConnectionDispatch; @@ -372,6 +374,10 @@ struct ImplSVData css::uno::Reference m_xCharClass; +#if defined _WIN32 + css::uno::Reference m_xSystemClipboard; +#endif + Link maDeInitHook; // LOK & headless backend specific hooks diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index ace085e89632..bfa5279ca4ca 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -484,6 +484,15 @@ void DeInitVCL() pSVData->maCtrlData.mpDisclosureMinus.reset(); pSVData->mpDefaultWin.disposeAndClear(); +#if defined _WIN32 + // See GetSystemClipboard (vcl/source/treelist/transfer2.cxx): + if (auto const comp = css::uno::Reference( + pSVData->m_xSystemClipboard, css::uno::UNO_QUERY)) + { + comp->dispose(); + } +#endif + #ifndef NDEBUG DbgGUIDeInitSolarMutexCheck(); #endif diff --git a/vcl/source/treelist/transfer2.cxx b/vcl/source/treelist/transfer2.cxx index 0a6f7528b252..fbb4c2a82768 100644 --- a/vcl/source/treelist/transfer2.cxx +++ b/vcl/source/treelist/transfer2.cxx @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include +#include using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; @@ -462,6 +464,26 @@ void TransferDataContainer::DragFinished( sal_Int8 nDropAction ) Reference 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; try { @@ -470,6 +492,7 @@ Reference GetSystemClipboard() } catch (DeploymentException const &) {} return xClipboard; +#endif } Reference GetSystemPrimarySelection()