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:
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user