From d26758044c55c0111ccd5e2c4d161f74c06d1771 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 12 Jan 2018 17:16:02 +0100 Subject: [PATCH] Don't call wxWakeUpIdle() with a lock in wxProgressDialog This can result in deadlocks because wxWakeUpIdle(), admittedly rather unexpectedly, can result in dispatching a message in the main thread, which could reacquire the same lock again. --- src/msw/progdlg.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/msw/progdlg.cpp b/src/msw/progdlg.cpp index 46416402c5..2f1131a5dc 100644 --- a/src/msw/progdlg.cpp +++ b/src/msw/progdlg.cpp @@ -1133,6 +1133,18 @@ wxProgressDialogTaskRunner::TaskDialogCallbackProc LONG_PTR dwRefData ) { + if ( uNotification == TDN_CREATED ) + { + // The main thread may be sitting in an event dispatching loop waiting + // for this dialog to be shown, so make sure it does wake up now that + // it is. Notice that we must do it from here and not from inside the + // block below in which sharedData is locked as otherwise we could + // deadlock if wxWakeUpIdle() dispatched some event which tried to call + // any of wxProgressDialog methods, which also lock this data, from the + // main thread. + wxWakeUpIdle(); + } + bool endDialog = false; // Block for shared data critical section. @@ -1148,10 +1160,6 @@ wxProgressDialogTaskRunner::TaskDialogCallbackProc // Store the HWND for the main thread use. sharedData->m_hwnd = hwnd; - // The main thread is sitting in an event dispatching loop waiting - // for this dialog to be shown, so make sure it does get an event. - wxWakeUpIdle(); - // Set the maximum value and disable Close button. ::SendMessage( hwnd, TDM_SET_PROGRESS_BAR_RANGE,