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.
This commit is contained in:
Vadim Zeitlin
2018-01-12 17:16:02 +01:00
parent 6bd8cb964b
commit d26758044c

View File

@@ -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,