[Libreoffice-commits] core.git: include/vcl vcl/inc vcl/source
Mike Kaganski (via logerrit)
logerrit at kemper.freedesktop.org
Fri Dec 4 15:03:00 UTC 2020
include/vcl/scheduler.hxx | 1 +
vcl/inc/schedulerimpl.hxx | 19 +++++++++++++++++++
vcl/source/app/svapp.cxx | 1 +
3 files changed, 21 insertions(+)
New commits:
commit 46f6b39c6d8acd064bafb2416feba757ba0d0fbc
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Fri Dec 4 15:13:13 2020 +0300
Commit: Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Fri Dec 4 16:02:11 2020 +0100
Unlock scheduler when calling ProcessEventsToIdle
When processing the events, solar mutex will be temporarily released,
and then it's possible that another thread will acquire solar mutex
and try to lock scheduler. This will result in deadlock.
Seen in CppunitTest_sw_core_undo that deadlocked locally on Windows
frequently.
Main thread call stack:
win32u.dll!NtUserMsgWaitForMultipleObjectsEx
()
user32.dll!RealMsgWaitForMultipleObjectsEx()
sal3.dll!osl_waitCondition(void * Condition, const TimeValue * pTimeout) Line 82
vclplug_winlo.dll!osl::Condition::wait(const TimeValue * pTimeout) Line 120
vclplug_winlo.dll!SalYieldMutex::doAcquire(unsigned long nLockCount) Line 159
comphelper.dll!comphelper::SolarMutex::acquire(unsigned long nLockCount) Line 87
vclplug_winlo.dll!ImplSalYieldMutexAcquireWithWait(unsigned long nCount) Line 204
vclplug_winlo.dll!WinSalTimer::ImplHandleElapsedTimer() Line 163
vclplug_winlo.dll!WinSalTimer::ImplHandle_WM_TIMER(unsigned __int64 aWPARAM) Line 197
vclplug_winlo.dll!SalComWndProc(HWND__ * __formal, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam, bool & rDef) Line 638
vclplug_winlo.dll!SalComWndProcW(HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 665
user32.dll!UserCallWinProcCheckWow()
user32.dll!DispatchMessageWorker()
vclplug_winlo.dll!ImplSalDispatchMessage(const tagMSG * pMsg) Line 426
vclplug_winlo.dll!ImplSalYield(bool bWait, bool bHandleAllCurrentEvents) Line 457
vclplug_winlo.dll!WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) Line 528
vcllo.dll!ImplYield(bool i_bWait, bool i_bAllEvents) Line 447
vcllo.dll!Application::Reschedule(bool i_bAllEvents) Line 461
vcllo.dll!Scheduler::ProcessEventsToIdle() Line 466
vcllo.dll!Scheduler::ImplDeInitScheduler() Line 129
vcllo.dll!DeInitVCL() Line 483
vclbootstrapprotector.dll!`anonymous namespace'::Protector::~Protector() Line 34
vclbootstrapprotector.dll!`anonymous namespace'::Protector::`scalar deleting destructor'(unsigned int)
cppunitd_dll.dll!CppUnit::ProtectorChain::pop() Line 56
cppunitd_dll.dll!CppUnit::TestResult::popProtector() Line 197
cppunittester.exe!`anonymous namespace'::ProtectedFixtureFunctor::run() Line 332
cppunittester.exe!sal_main() Line 473
cppunittester.exe!main(int argc, char * * argv) Line 380
cppunittester.exe!invoke_main() Line 79
cppunittester.exe!__scrt_common_main_seh() Line 288
cppunittester.exe!__scrt_common_main() Line 331
cppunittester.exe!mainCRTStartup() Line 17
kernel32.dll!BaseThreadInitThunk
()
ntdll.dll!RtlUserThreadStart
()
Clipboard thread call stack:
ntdll.dll!NtWaitForAlertByThreadId
()
ntdll.dll!RtlpWaitOnAddressWithTimeout()
ntdll.dll!RtlpWaitOnAddress()
ntdll.dll!RtlpWaitOnCriticalSection()
ntdll.dll!RtlpEnterCriticalSectionContended()
ntdll.dll!RtlEnterCriticalSection
()
sal3.dll!osl_acquireMutex(_oslMutexImpl * Mutex) Line 66
vcllo.dll!osl::Mutex::acquire() Line 57
vcllo.dll!SchedulerMutex::acquire(unsigned long nLockCount) Line 213
vcllo.dll!Scheduler::Lock(unsigned long nLockCount) Line 237
vcllo.dll!SchedulerGuard::SchedulerGuard() Line 60
vcllo.dll!Task::~Task() Line 660
vcllo.dll!Timer::~Timer() Line 61
vcllo.dll!Idle::~Idle()
svxcorelo.dll!SdrPaintView::~SdrPaintView() Line 189
svxcorelo.dll!SdrSnapView::~SdrSnapView() Line 200
svxcorelo.dll!SdrMarkView::~SdrMarkView() Line 193
svxcorelo.dll!SdrEditView::~SdrEditView() Line 125
svxcorelo.dll!SdrPolyEditView::~SdrPolyEditView() Line 58
svxcorelo.dll!SdrGlueEditView::~SdrGlueEditView() Line 40
svxcorelo.dll!SdrObjEditView::~SdrObjEditView() Line 95
svxcorelo.dll!SdrExchangeView::~SdrExchangeView()
svxcorelo.dll!SdrDragView::~SdrDragView() Line 65
svxcorelo.dll!SdrCreateView::~SdrCreateView() Line 200
svxcorelo.dll!SdrView::~SdrView() Line 159
swlo.dll!SdrView::`scalar deleting destructor'(unsigned int)
swlo.dll!std::default_delete<SdrView>::operator()(SdrView * _Ptr) Line 2537
swlo.dll!std::unique_ptr<SdrView,std::default_delete<SdrView>>::~unique_ptr<SdrView,std::default_delete<SdrView>>() Line 2649
swlo.dll!SwDrawFrameFormat::MakeGraphic(ImageMap * __formal) Line 7491
swlo.dll!OutHTML_FrameFormatAsImage(Writer & rWrt, const SwFrameFormat & rFrameFormat) Line 1746
swlo.dll!SwHTMLWriter::OutFrameFormat(AllHtmlFlags nMode, const SwFrameFormat & rFrameFormat, const SdrObject * pSdrObject) Line 507
swlo.dll!SwHTMLWriter::OutFlyFrame(unsigned __int64 nNdIdx, long nContentIdx, HtmlPosition nPos, HTMLOutContext * pContext) Line 401
swlo.dll!OutHTML_SwTextNode(Writer & rWrt, const SwContentNode & rNode) Line 2509
swlo.dll!SwHTMLWriter::Out_SwDoc(SwPaM * pPam) Line 834
swlo.dll!SwHTMLWriter::WriteStream() Line 471
swlo.dll!Writer::Write(SwPaM & rPaM, SvStream & rStrm, const rtl::OUString * pFName) Line 272
swlo.dll!SwWriter::Write(const tools::SvRef<Writer> & rxWriter, const rtl::OUString * pRealFileName) Line 861
swlo.dll!SwTransferable::WriteObject(tools::SvRef<SotStorageStream> & xStream, void * pObject, unsigned long nObjectType, const com::sun::star::datatransfer::DataFlavor & __formal) Line 823
vcllo.dll!TransferableHelper::SetObject(void * pUserObject, unsigned long nUserObjectId, const com::sun::star::datatransfer::DataFlavor & rFlavor) Line 879
swlo.dll!SwTransferable::GetData(const com::sun::star::datatransfer::DataFlavor & rFlavor, const rtl::OUString & rDestDoc) Line 619
vcllo.dll!TransferableHelper::getTransferData2(const com::sun::star::datatransfer::DataFlavor & rFlavor, const rtl::OUString & rDestDoc) Line 389
vcllo.dll!TransferableHelper::getTransferData(const com::sun::star::datatransfer::DataFlavor & rFlavor) Line 287
vclplug_winlo.dll!CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium(tagFORMATETC & fetc, tagSTGMEDIUM & stgmedium) Line 516
vclplug_winlo.dll!CXTDataObject::renderSynthesizedFormatAndSetupStgMedium(tagFORMATETC & fetc, tagSTGMEDIUM & stgmedium) Line 419
vclplug_winlo.dll!`CXTDataObject::GetData'::`1'::catch$1() Line 269
vcruntime140_1d.dll!_CallSettingFrame_LookupContinuationIndex() Line 98
vcruntime140_1d.dll!__FrameHandler4::CxxCallCatchBlock(_EXCEPTION_RECORD * pExcept) Line 1367
ntdll.dll!RcConsolidateFrames
()
vclplug_winlo.dll!CXTDataObject::GetData(tagFORMATETC * pFormatetc, tagSTGMEDIUM * pmedium) Line 261
vclplug_winlo.dll!CXNotifyingDataObject::GetData(tagFORMATETC * pFormatetc, tagSTGMEDIUM * pmedium) Line 86
ole32.dll!HandleFromHandle(IDataObject * pDataObj, tagFORMATETC * pformatetc, tagSTGMEDIUM * pmedium) Line 2048
ole32.dll!RenderCurrentFormat(HWND__ * hClipWnd, unsigned int cf, tagSTGMEDIUM * pmedium, IDataObject * pDataObj) Line 4057
ole32.dll!RenderFormat(HWND__ * hClipWnd, unsigned int cf, IDataObject * pDataObj, void * pvMTADataObject) Line 4191
ole32.dll!ClipboardWndProc(HWND__ * hWnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 683
user32.dll!UserCallWinProcCheckWow()
user32.dll!DispatchClientMessage()
user32.dll!__fnDWORD
()
ntdll.dll!KiUserCallbackDispatcherContinue
()
win32u.dll!NtUserGetMessage
()
user32.dll!GetMessageW()
vclplug_winlo.dll!CMtaOleClipboard::run() Line 654
vclplug_winlo.dll!CMtaOleClipboard::oleThreadProc(void * pParam) Line 676
ucrtbased.dll!thread_start<unsigned int (__cdecl*)(void *),1>(void * const parameter) Line 97
kernel32.dll!BaseThreadInitThunk
()
ntdll.dll!RtlUserThreadStart
()
Main thread hold solar mutex when it locked scheduler in
ImplDeInitScheduler; then it released solar mutex in
WinSalInstance::DoYield, and finally tried to acquire it again in
WinSalTimer::ImplHandleElapsedTimer.
At the same time, clipboard thread acquired solar mutex in
TransferableHelper::getTransferData2. Then it attempted to lock
scheduler in Task::~Task.
Change-Id: I2ac87c8ac298104043f5b9b5d6760bea0f408f54
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107218
Tested-by: Mike Kaganski <mike.kaganski at collabora.com>
Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
index 9318b2109641..955043116b50 100644
--- a/include/vcl/scheduler.hxx
+++ b/include/vcl/scheduler.hxx
@@ -27,6 +27,7 @@ struct ImplSchedulerContext;
class VCL_DLLPUBLIC Scheduler final
{
friend class SchedulerGuard;
+ friend class SchedulerGuardReleaser;
friend class Task;
Scheduler() = delete;
diff --git a/vcl/inc/schedulerimpl.hxx b/vcl/inc/schedulerimpl.hxx
index ffb08084252c..d95fb0157880 100644
--- a/vcl/inc/schedulerimpl.hxx
+++ b/vcl/inc/schedulerimpl.hxx
@@ -65,6 +65,25 @@ public:
}
};
+class SchedulerGuardReleaser final
+{
+public:
+ SchedulerGuardReleaser()
+ {
+ Scheduler::Lock();
+ m_nLockCount = Scheduler::Unlock(true) - 1;
+ }
+
+ ~SchedulerGuardReleaser()
+ {
+ if (m_nLockCount)
+ Scheduler::Lock(m_nLockCount);
+ }
+
+private:
+ sal_uInt32 m_nLockCount;
+};
+
#endif // INCLUDED_VCL_INC_SCHEDULERIMPL_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index f91375e77edd..0b30a0b6b688 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -462,6 +462,7 @@ bool Application::Reschedule( bool i_bAllEvents )
void Scheduler::ProcessEventsToIdle()
{
+ SchedulerGuardReleaser aReleaser;
int nSanity = 1;
while( Application::Reschedule( true ) )
{
More information about the Libreoffice-commits
mailing list