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
|
LONG_PTR dwRefData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
bool endDialog = false;
|
||||||
|
|
||||||
|
// Block for shared data critical section.
|
||||||
|
{
|
||||||
wxProgressDialogSharedData * const sharedData =
|
wxProgressDialogSharedData * const sharedData =
|
||||||
(wxProgressDialogSharedData *) dwRefData;
|
(wxProgressDialogSharedData *) dwRefData;
|
||||||
|
|
||||||
@@ -1230,10 +1234,25 @@ wxProgressDialogTaskRunner::TaskDialogCallbackProc
|
|||||||
(sharedData->m_state == wxProgressDialog::Finished &&
|
(sharedData->m_state == wxProgressDialog::Finished &&
|
||||||
sharedData->m_style & wxPD_AUTO_HIDE) )
|
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;
|
sharedData->m_notifications = 0;
|
||||||
|
|
||||||
|
if ( endDialog )
|
||||||
|
break;
|
||||||
|
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Leave shared data critical section.
|
||||||
|
|
||||||
|
if ( endDialog )
|
||||||
|
{
|
||||||
|
::EndDialog( hwnd, IDCLOSE );
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user