Merge pull request #8763 from JosJuice/panic-alert-deadlock-gpu

DolphinQt: Fix the panic alert deadlock, dual core edition
This commit is contained in:
Admiral H. Curtiss
2022-05-16 02:21:14 +02:00
committed by GitHub
5 changed files with 83 additions and 25 deletions

View File

@ -41,21 +41,26 @@ static bool QtMsgAlertHandler(const char* caption, const char* text, bool yes_no
Common::MsgType style)
{
const bool called_from_cpu_thread = Core::IsCPUThread();
const bool called_from_gpu_thread = Core::IsGPUThread();
std::optional<bool> r = RunOnObject(QApplication::instance(), [&] {
Common::ScopeGuard scope_guard(&Core::UndeclareAsCPUThread);
// If we were called from the CPU/GPU thread, set us as the CPU/GPU thread.
// This information is used in order to avoid deadlocks when calling e.g.
// Host::SetRenderFocus or Core::RunAsCPUThread. (Host::SetRenderFocus
// can get called automatically when a dialog steals the focus.)
Common::ScopeGuard cpu_scope_guard(&Core::UndeclareAsCPUThread);
Common::ScopeGuard gpu_scope_guard(&Core::UndeclareAsGPUThread);
if (!called_from_cpu_thread)
cpu_scope_guard.Dismiss();
if (!called_from_gpu_thread)
gpu_scope_guard.Dismiss();
if (called_from_cpu_thread)
{
// Temporarily declare this as the CPU thread to avoid getting a deadlock if any DolphinQt
// code calls RunAsCPUThread while the CPU thread is blocked on this function returning.
// Notably, if the panic alert steals focus from RenderWidget, Host::SetRenderFocus gets
// called, which can attempt to use RunAsCPUThread to get us out of exclusive fullscreen.
Core::DeclareAsCPUThread();
}
else
{
scope_guard.Dismiss();
}
if (called_from_gpu_thread)
Core::DeclareAsGPUThread();
ModalMessageBox message_box(QApplication::activeWindow(), Qt::ApplicationModal);
message_box.setWindowTitle(QString::fromUtf8(caption));