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.
This commit is contained in:
Vadim Zeitlin
2017-10-29 20:31:33 +01:00
parent d7ec02636a
commit 2b8e84ca49

View File

@@ -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;
}