summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2020-01-24 08:14:15 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2020-01-24 10:01:55 +0100
commit9a2fc64b49b4a3067ba78648e3fcc73390717c80 (patch)
treece15e4104a5840198ba725846ab14430e2071ba1 /vcl
parent70457e664cc12958f1938f0154b9c085525f4c26 (diff)
Prevent deadlock in DeInitVCL() on Windows
Seen in local make check build: 1. A unit test is being finished, calling DeInitVCL() in main thread, which holds solar mutex; it is now attempting to dispose clipboard listener, which needs to lock CWinClipbImpl::s_aMutex: ===== sysdtrans.dll!osl::Guard<osl::Mutex>::Guard<osl::Mutex>(osl::Mutex & t) Line 136 at C:\lo\src\core\include\osl\mutex.hxx(136) sysdtrans.dll!CWinClipbImpl::~CWinClipbImpl() Line 67 at C:\lo\src\core\dtrans\source\win32\clipb\WinClipbImpl.cxx(67) sysdtrans.dll!CWinClipbImpl::`scalar deleting destructor'(unsigned int) sysdtrans.dll!std::default_delete<CWinClipbImpl>::operator()(CWinClipbImpl * _Ptr) Line 1765 at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\memory(1765) sysdtrans.dll!std::unique_ptr<CWinClipbImpl,std::default_delete<CWinClipbImpl>>::reset(CWinClipbImpl * _Ptr) Line 1908 at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\memory(1908) sysdtrans.dll!CWinClipboard::disposing() Line 220 at C:\lo\src\core\dtrans\source\win32\clipb\WinClipboard.cxx(220) cppuhelper3MSC.dll!cppu::WeakComponentImplHelperBase::dispose() Line 102 at C:\lo\src\core\cppuhelper\source\implbase.cxx(102) sysdtrans.dll!cppu::PartialWeakComponentImplHelper<com::sun::star::datatransfer::clipboard::XSystemClipboard,com::sun::star::datatransfer::clipboard::XFlushableClipboard,com::sun::star::lang::XServiceInfo>::dispose() Line 90 at C:\lo\src\core\include\cppuhelper\compbase.hxx(90) vcllo.dll!DeInitVCL() Line 492 at C:\lo\src\core\vcl\source\app\svmain.cxx(492) vclbootstrapprotector.dll!`anonymous namespace'::Protector::~Protector() Line 32 at C:\lo\src\core\test\source\vclbootstrapprotector.cxx(32) vclbootstrapprotector.dll!`anonymous namespace'::Protector::`scalar deleting destructor'(unsigned int) cppunitd_dll.dll!CppUnit::ProtectorChain::pop() Line 56 at C:\lo\src\build\workdir\UnpackedTarball\cppunit\src\cppunit\ProtectorChain.cpp(56) cppunitd_dll.dll!CppUnit::TestResult::popProtector() Line 197 at C:\lo\src\build\workdir\UnpackedTarball\cppunit\src\cppunit\TestResult.cpp(197) cppunittester.exe!`anonymous namespace'::ProtectedFixtureFunctor::run() Line 325 at C:\lo\src\core\sal\cppunittester\cppunittester.cxx(325) cppunittester.exe!sal_main() Line 466 at C:\lo\src\core\sal\cppunittester\cppunittester.cxx(466) cppunittester.exe!main(int argc, char * * argv) Line 373 at C:\lo\src\core\sal\cppunittester\cppunittester.cxx(373) ===== 2. Simultaneously, clipboard listener thread calls onClipboardContentChanged, which has locked CWinClipbImpl::s_aMutex, and now it's trying to post user event in SfxClipboardChangeListener::changedContents, which needs to lock solar mutex in ImplGetDefaultContextWindow: ===== comphelper.dll!comphelper::SolarMutex::acquire(unsigned long nLockCount) Line 87 at C:\lo\src\core\include\comphelper\solarmutex.hxx(87) vcllo.dll!osl::Guard<comphelper::SolarMutex>::Guard<comphelper::SolarMutex>(comphelper::SolarMutex & t) Line 136 at C:\lo\src\core\include\osl\mutex.hxx(136) vcllo.dll!SolarMutexGuard::SolarMutexGuard() Line 1343 at C:\lo\src\core\include\vcl\svapp.hxx(1343) vcllo.dll!ImplGetDefaultContextWindow() Line 227 at C:\lo\src\core\vcl\source\app\svdata.cxx(227) vcllo.dll!ImplGetDefaultWindow() Line 217 at C:\lo\src\core\vcl\source\app\svdata.cxx(217) vcllo.dll!Application::PostUserEvent(const Link<void *,void> & rLink, void * pCaller, bool bReferenceLink) Line 1000 at C:\lo\src\core\vcl\source\app\svapp.cxx(1000) sfxlo.dll!SfxClipboardChangeListener::changedContents(const com::sun::star::datatransfer::clipboard::ClipboardEvent & __formal) Line 215 at C:\lo\src\core\sfx2\source\view\viewsh.cxx(215) sysdtrans.dll!CWinClipboard::notifyAllClipboardListener() Line 189 at C:\lo\src\core\dtrans\source\win32\clipb\WinClipboard.cxx(189) sysdtrans.dll!CWinClipbImpl::onClipboardContentChanged() Line 179 at C:\lo\src\core\dtrans\source\win32\clipb\WinClipbImpl.cxx(179) sysdtrans.dll!CMtaOleClipboard::clipboardChangedNotifierThreadProc(void * pParam) Line 705 at C:\lo\src\core\dtrans\source\win32\clipb\MtaOleClipb.cxx(705) ucrtbased.dll!thread_start<unsigned int (__cdecl*)(void *),1>(void * const parameter) Line 97 at minkernel\crts\ucrt\src\appcrt\startup\thread.cpp(97) kernel32.dll!BaseThreadInitThunk() ntdll.dll!RtlUserThreadStart() ===== => the two threads deadlock waiting for mutexes locked in each other. Resolve it by using SolarMutexReleaser around the call disposing the clipboard listener in DeInitVCL. An alternative could be using solar mutex instead of CWinClipbImpl::s_aMutex. Change-Id: Ifd76ce5a7d969a568539602eae2139b4ef0c5858 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87318 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/app/svmain.cxx3
1 files changed, 2 insertions, 1 deletions
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index bfa5279ca4ca..998ece19dc21 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -489,7 +489,8 @@ void DeInitVCL()
if (auto const comp = css::uno::Reference<css::lang::XComponent>(
pSVData->m_xSystemClipboard, css::uno::UNO_QUERY))
{
- comp->dispose();
+ SolarMutexReleaser r; // unblock pending "clipboard content changed" notifications
+ comp->dispose(); // will use CWinClipbImpl::s_aMutex
}
#endif