[Libreoffice-commits] core.git: vcl/source vcl/vclplug_win.component vcl/win

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Mon Sep 28 18:49:34 UTC 2020


 vcl/source/app/svmain.cxx       |    1 +
 vcl/vclplug_win.component       |    3 +++
 vcl/win/dtrans/WinClipboard.cxx |   32 +++++++++++++++++++++++++++++---
 vcl/win/dtrans/WinClipboard.hxx |    2 ++
 4 files changed, 35 insertions(+), 3 deletions(-)

New commits:
commit 1dd01410e6c39c0e51bfb406c1cbb02569bd8dd3
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Mon Sep 28 15:45:08 2020 +0200
Commit:     Stephan Bergmann <sbergman at redhat.com>
CommitDate: Mon Sep 28 20:48:49 2020 +0200

    Destroy CWinClipboard sufficiently early
    
    At least with a local --host=i686-pc-cygwin --enable-dbgutil Windows `make
    unitcheck slowcheck` build (i.e., similar to
    <https://ci.libreoffice.org/job/gerrit_windows/>, which is often failing with
    aborted builds, presumably due to hung tests), I could once see a CppunitTest
    hang with just a main thread left at
    
    > ntdll.dll!77acc62c()
    > [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
    > KernelBase.dll!77492863()
    > rpcrt4.dll!773e55d9()
    > rpcrt4.dll!77466afb()
    > combase.dll!7576a02a()
    > combase.dll!7565072f()
    > combase.dll!7564b2dd()
    > combase.dll!7564b246()
    > combase.dll!756498a4()
    > combase.dll!757690ef()
    > vclplug_winlo.dll!sal::systools::COMReference<IDataObject>::release() Line 166
    >         at C:\lo\core\include\systools\win32\comtools.hxx(166)
    > vclplug_winlo.dll!sal::systools::COMReference<IDataObject>::~COMReference<IDataObject>() Line 101
    >         at C:\lo\core\include\systools\win32\comtools.hxx(101)
    > vclplug_winlo.dll!CAPNDataObject::~CAPNDataObject() Line 97
    >         at C:\lo\core\vcl\win\dtrans\APNDataObject.cxx(97)
    > vclplug_winlo.dll!CAPNDataObject::`scalar deleting destructor'(unsigned int)
    > vclplug_winlo.dll!CAPNDataObject::Release() Line 137
    >         at C:\lo\core\vcl\win\dtrans\APNDataObject.cxx(137)
    > vclplug_winlo.dll!sal::systools::COMReference<IDataObject>::release() Line 166
    >         at C:\lo\core\include\systools\win32\comtools.hxx(166)
    > vclplug_winlo.dll!sal::systools::COMReference<IDataObject>::~COMReference<IDataObject>() Line 101
    >         at C:\lo\core\include\systools\win32\comtools.hxx(101)
    > vclplug_winlo.dll!CDOTransferable::~CDOTransferable()
    > vclplug_winlo.dll!CDOTransferable::`scalar deleting destructor'(unsigned int)
    > cppuhelper3MSC.dll!cppu::OWeakObject::release() Line 233
    >         at C:\lo\core\cppuhelper\source\weak.cxx(233)
    > vclplug_winlo.dll!cppu::WeakImplHelper<com::sun::star::datatransfer::XTransferable,com::sun::star::datatransfer::XSystemTransferable>::release() Line 115
    >         at C:\lo\core\include\cppuhelper\implbase.hxx(115)
    > vclplug_winlo.dll!com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable>::~Reference<com::sun::star::datatransfer::XTransferable>() Line 110
    >         at C:\lo\core\include\com\sun\star\uno\Reference.hxx(110)
    > vclplug_winlo.dll!CWinClipboard::~CWinClipboard() Line 73
    >         at C:\lo\core\vcl\win\dtrans\WinClipboard.cxx(73)
    > vclplug_winlo.dll!CWinClipboard::`scalar deleting destructor'(unsigned int)
    > cppuhelper3MSC.dll!cppu::OWeakObject::release() Line 233
    >         at C:\lo\core\cppuhelper\source\weak.cxx(233)
    > cppuhelper3MSC.dll!cppu::WeakComponentImplHelperBase::release() Line 86
    >         at C:\lo\core\cppuhelper\source\implbase.cxx(86)
    > vclplug_winlo.dll!cppu::PartialWeakComponentImplHelper<com::sun::star::datatransfer::clipboard::XSystemClipboard,com::sun::star::datatransfer::clipboard::XFlushableClipboard,com::sun::star::lang::XServiceInfo>::release() Line 86
    >         at C:\lo\core\include\cppuhelper\compbase.hxx(86)
    > vcllo.dll!com::sun::star::uno::Reference<com::sun::star::datatransfer::clipboard::XClipboard>::~Reference<com::sun::star::datatransfer::clipboard::XClipboard>() Line 110
    >         at C:\lo\core\include\com\sun\star\uno\Reference.hxx(110)
    > vcllo.dll!ImplSVData::~ImplSVData() Line 485
    >         at C:\lo\core\vcl\source\app\svdata.cxx(485)
    > vcllo.dll!`rtl::Static<ImplSVData,`anonymous namespace'::private_aImplSVData>::get'::`2'::`dynamic atexit destructor for 'instance''()
    > ucrtbased.dll!72f16942()
    > ucrtbased.dll!72f16523()
    > ucrtbased.dll!72f010ac()
    > ntdll.dll!77ad9476()
    > ntdll.dll!77ad9476()
    > ntdll.dll!77ad93f0()
    > ntdll.dll!77afcbd8()
    > ntdll.dll!77aefdc8()
    > kernel32.dll!77736a14()
    > ntdll.dll!77aeab4f()
    > ntdll.dll!77aeab1a()
    
    i.e., the ImplSVData::m_xSystemClipboard introduced by
    974ea67a7c345a8be98c5aaa59baf9b07959b708 "tdf#129930: Dispose SystemClipboard
    service early enough" for some reason causing a COM issue when the static
    ImplSVData aImplSVData (vcl/source/app/svdata.cxx) gets destroyed during exit.
    
    And with this change to vcl/source/app/svmain.cxx, I could still see
    CppunitTests hang with just a main thread left at
    
    > [External Code]
    > vclplug_winlo.dll!sal::systools::COMReference<IDataObject>::release() Line 166
    >         at C:\lo\core\include\systools\win32\comtools.hxx(166)
    > vclplug_winlo.dll!sal::systools::COMReference<IDataObject>::~COMReference<IDataObject>() Line 101
    >         at C:\lo\core\include\systools\win32\comtools.hxx(101)
    > vclplug_winlo.dll!CAPNDataObject::~CAPNDataObject() Line 97
    >         at C:\lo\core\vcl\win\dtrans\APNDataObject.cxx(97)
    > [External Code]
    > vclplug_winlo.dll!CAPNDataObject::Release() Line 137
    >         at C:\lo\core\vcl\win\dtrans\APNDataObject.cxx(137)
    > vclplug_winlo.dll!sal::systools::COMReference<IDataObject>::release() Line 166
    >         at C:\lo\core\include\systools\win32\comtools.hxx(166)
    > vclplug_winlo.dll!sal::systools::COMReference<IDataObject>::~COMReference<IDataObject>() Line 101
    >         at C:\lo\core\include\systools\win32\comtools.hxx(101)
    > [External Code]
    > cppuhelper3MSC.dll!cppu::OWeakObject::release() Line 233
    >         at C:\lo\core\cppuhelper\source\weak.cxx(233)
    > vclplug_winlo.dll!cppu::WeakImplHelper<com::sun::star::datatransfer::XTransferable,com::sun::star::datatransfer::XSystemTransferable>::release() Line 115
    >         at C:\lo\core\include\cppuhelper\implbase.hxx(115)
    > vclplug_winlo.dll!com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable>::~Reference<com::sun::star::datatransfer::XTransferable>() Line 110
    >         at C:\lo\core\include\com\sun\star\uno\Reference.hxx(110)
    > vclplug_winlo.dll!CWinClipboard::~CWinClipboard() Line 73
    >         at C:\lo\core\vcl\win\dtrans\WinClipboard.cxx(73)
    > [External Code]
    > cppuhelper3MSC.dll!cppu::OWeakObject::release() Line 233
    >         at C:\lo\core\cppuhelper\source\weak.cxx(233)
    > cppuhelper3MSC.dll!cppu::WeakComponentImplHelperBase::release() Line 86
    >         at C:\lo\core\cppuhelper\source\implbase.cxx(86)
    > vclplug_winlo.dll!cppu::PartialWeakComponentImplHelper<com::sun::star::datatransfer::clipboard::XSystemClipboard,com::sun::star::datatransfer::clipboard::XFlushableClipboard,com::sun::star::lang::XServiceInfo>::release() Line 86
    >         at C:\lo\core\include\cppuhelper\compbase.hxx(86)
    > vclplug_winlo.dll!rtl::Reference<CWinClipboard>::~Reference<CWinClipboard>() Line 113
    >         at C:\lo\core\include\rtl\ref.hxx(113)
    > [External Code]
    
    i.e., the static rtl::Reference<CWinClipboard> g_Instance
    (vcl/win/dtrans/WinClipboard.cxx) introduced by
    b76e903ccc83d0ccf0c6548782622638dd8a0ee5 "dtrans/clipboard: create instances
    with uno constructors" still causing the same COM issue during exit.
    
    Change-Id: Ib89d37a4fcb4b4a25e552a9dd14a96ade8e40309
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103559
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index 2093f66a5ad7..d16160ac307a 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -495,6 +495,7 @@ void DeInitVCL()
         SolarMutexReleaser r; // unblock pending "clipboard content changed" notifications
         comp->dispose(); // will use CWinClipbImpl::s_aMutex
     }
+    pSVData->m_xSystemClipboard.clear();
 #endif
 
 #ifndef NDEBUG
diff --git a/vcl/vclplug_win.component b/vcl/vclplug_win.component
index 907694991895..db79a027510e 100644
--- a/vcl/vclplug_win.component
+++ b/vcl/vclplug_win.component
@@ -42,5 +42,8 @@
   <implementation name="com.sun.star.datatransfer.clipboard.ClipboardW32"
         constructor="dtrans_CWinClipboard_get_implementation">
     <service name="com.sun.star.datatransfer.clipboard.SystemClipboard"/>
+    <!-- Fake singleton so the servicemanager shuts us down and we can clean up our global instance
+         var: -->
+    <singleton name="com.sun.star.datatransfer.clipboard.theSystemClipboard"/>
   </implementation>
 </component>
diff --git a/vcl/win/dtrans/WinClipboard.cxx b/vcl/win/dtrans/WinClipboard.cxx
index 7317d8467827..17477fd8d16d 100644
--- a/vcl/win/dtrans/WinClipboard.cxx
+++ b/vcl/win/dtrans/WinClipboard.cxx
@@ -17,12 +17,17 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <sal/config.h>
+
+#include <mutex>
+
 #include <osl/diagnose.h>
 #include <com/sun/star/datatransfer/clipboard/ClipboardEvent.hpp>
 #include <com/sun/star/lang/DisposedException.hpp>
 #include <com/sun/star/lang/IllegalArgumentException.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/weak.hxx>
 #include <rtl/ref.hxx>
 
 #include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp>
@@ -296,13 +301,27 @@ uno::Sequence<OUString> SAL_CALL CWinClipboard::getSupportedServiceNames()
     return { "com.sun.star.datatransfer.clipboard.SystemClipboard" };
 }
 
+namespace
+{
+std::mutex g_InstanceGuard;
+rtl::Reference<CWinClipboard> g_Instance;
+bool g_Disposed = false;
+}
+
 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
 dtrans_CWinClipboard_get_implementation(css::uno::XComponentContext* context,
                                         css::uno::Sequence<css::uno::Any> const&)
 {
-    static rtl::Reference<CWinClipboard> g_Instance(new CWinClipboard(context, ""));
-    g_Instance->acquire();
-    return static_cast<cppu::OWeakObject*>(g_Instance.get());
+    std::scoped_lock l(g_InstanceGuard);
+    if (g_Disposed)
+    {
+        return nullptr;
+    }
+    if (!g_Instance.is())
+    {
+        g_Instance.set(new CWinClipboard(context, ""));
+    }
+    return cppu::acquire(static_cast<cppu::OWeakObject*>(g_Instance.get()));
 }
 
 void CWinClipboard::onReleaseDataObject(CXNotifyingDataObject* theCaller)
@@ -339,4 +358,11 @@ void WINAPI CWinClipboard::onClipboardContentChanged()
     }
 }
 
+void CWinClipboard::disposing()
+{
+    std::scoped_lock l(g_InstanceGuard);
+    g_Instance.clear();
+    g_Disposed = true;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/dtrans/WinClipboard.hxx b/vcl/win/dtrans/WinClipboard.hxx
index 1b0a05a3450d..984a07a22dd7 100644
--- a/vcl/win/dtrans/WinClipboard.hxx
+++ b/vcl/win/dtrans/WinClipboard.hxx
@@ -82,6 +82,8 @@ class CWinClipboard final
 
     static void WINAPI onClipboardContentChanged();
 
+    void SAL_CALL disposing() override;
+
 public:
     CWinClipboard(const css::uno::Reference<css::uno::XComponentContext>& rxContext,
                   const OUString& aClipboardName);


More information about the Libreoffice-commits mailing list