From 2b8e84ca493db01ce86334deb1cf63a326cb5058 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 29 Oct 2017 20:31:33 +0100 Subject: [PATCH] Avoid deadlock when closing the progress dialog Don't call EndDialog() while inside the critical section, this could (and did, sometimes) result in a deadlock if the main thread was trying to enter it in order to send us wxSPDD_DESTROYED notification as EndDialog() needs it to process some messages. --- src/msw/progdlg.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/msw/progdlg.cpp b/src/msw/progdlg.cpp index ce08c960c6..69ec144ebd 100644 --- a/src/msw/progdlg.cpp +++ b/src/msw/progdlg.cpp @@ -1103,6 +1103,10 @@ wxProgressDialogTaskRunner::TaskDialogCallbackProc LONG_PTR dwRefData ) { + bool endDialog = false; + + // Block for shared data critical section. + { wxProgressDialogSharedData * const sharedData = (wxProgressDialogSharedData *) dwRefData; @@ -1230,13 +1234,28 @@ wxProgressDialogTaskRunner::TaskDialogCallbackProc (sharedData->m_state == wxProgressDialog::Finished && sharedData->m_style & wxPD_AUTO_HIDE) ) { - ::EndDialog( hwnd, IDCLOSE ); + // Don't call EndDialog() from here as it could deadlock + // because we are inside the shared data critical section, do + // it below after leaving it instead. + endDialog = true; } sharedData->m_notifications = 0; + + if ( endDialog ) + break; + return S_FALSE; } + } // Leave shared data critical section. + + if ( endDialog ) + { + ::EndDialog( hwnd, IDCLOSE ); + return S_FALSE; + } + // Return anything. return S_OK; }