Qt: Fix crash on shutdown with BP mode open

This commit is contained in:
Stenzek 2024-03-31 20:39:16 +10:00 committed by Connor McLaughlin
parent 4d531384e9
commit 64b6dec56f
3 changed files with 20 additions and 11 deletions

View File

@ -1972,6 +1972,7 @@ void MainWindow::closeEvent(QCloseEvent* event)
// If there's no VM, we can just exit as normal.
if (!s_vm_valid || !m_display_created)
{
m_is_closing = true;
saveStateToConfig();
if (m_display_created)
g_emu_thread->stopFullscreenUI();
@ -2214,6 +2215,13 @@ std::optional<WindowInfo> MainWindow::acquireRenderWindow(bool recreate_window,
if (surfaceless)
return WindowInfo();
// very low-chance race here, if the user starts the fullscreen UI, and immediately closes the window.
if (m_is_closing)
{
m_display_created = false;
return std::nullopt;
}
createDisplayWidget(fullscreen, render_to_main);
std::optional<WindowInfo> wi = m_display_widget->getWindowInfo();

View File

@ -183,13 +183,13 @@ void EmuThread::startFullscreenUI(bool fullscreen)
// this should just set the flag so it gets automatically started
ImGuiManager::InitializeFullscreenUI();
m_run_fullscreen_ui = true;
m_run_fullscreen_ui.store(true, std::memory_order_release);
m_is_rendering_to_main = shouldRenderToMain();
m_is_fullscreen = fullscreen;
if (!MTGS::WaitForOpen())
{
m_run_fullscreen_ui = false;
m_run_fullscreen_ui.store(false, std::memory_order_release);
return;
}
@ -207,20 +207,21 @@ void EmuThread::stopFullscreenUI()
QMetaObject::invokeMethod(this, &EmuThread::stopFullscreenUI, Qt::QueuedConnection);
// wait until the host display is gone
while (!QtHost::IsVMValid() && MTGS::IsOpen())
// have to test the bool, because MTGS::IsOpen() goes false as soon as the close request happens.
while (m_run_fullscreen_ui.load(std::memory_order_acquire) || (!QtHost::IsVMValid() && MTGS::IsOpen()))
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
return;
}
if (m_run_fullscreen_ui)
{
m_run_fullscreen_ui = false;
emit onFullscreenUIStateChange(false);
}
if (MTGS::IsOpen() && !VMManager::HasValidVM())
MTGS::WaitForClose();
if (m_run_fullscreen_ui.load(std::memory_order_acquire))
{
m_run_fullscreen_ui.store(false, std::memory_order_release);
emit onFullscreenUIStateChange(false);
}
}
void EmuThread::startVM(std::shared_ptr<VMBootParameters> boot_params)

View File

@ -61,7 +61,7 @@ public:
__fi bool isExclusiveFullscreen() const { return m_is_exclusive_fullscreen; }
__fi bool isRenderingToMain() const { return m_is_rendering_to_main; }
__fi bool isSurfaceless() const { return m_is_surfaceless; }
__fi bool isRunningFullscreenUI() const { return m_run_fullscreen_ui; }
__fi bool isRunningFullscreenUI() const { return m_run_fullscreen_ui.load(std::memory_order_acquire); }
__fi bool isOnEmuThread() const { return (QThread::currentThread() == this); }
__fi bool isOnUIThread() const { return (QThread::currentThread() == m_ui_thread); }
@ -206,9 +206,9 @@ private:
QTimer* m_background_controller_polling_timer = nullptr;
std::atomic_bool m_shutdown_flag{false};
std::atomic_bool m_run_fullscreen_ui{false};
bool m_verbose_status = false;
bool m_run_fullscreen_ui = false;
bool m_is_rendering_to_main = false;
bool m_is_fullscreen = false;
bool m_is_exclusive_fullscreen = false;