Skip to content

Commit

Permalink
Qt: Fix crash on shutdown with BP mode open
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Apr 1, 2024
1 parent 4d53138 commit 64b6dec
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
8 changes: 8 additions & 0 deletions pcsx2-qt/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
17 changes: 9 additions & 8 deletions pcsx2-qt/QtHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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)
if (MTGS::IsOpen() && !VMManager::HasValidVM())
MTGS::WaitForClose();

if (m_run_fullscreen_ui.load(std::memory_order_acquire))
{
m_run_fullscreen_ui = false;
m_run_fullscreen_ui.store(false, std::memory_order_release);
emit onFullscreenUIStateChange(false);
}

if (MTGS::IsOpen() && !VMManager::HasValidVM())
MTGS::WaitForClose();
}

void EmuThread::startVM(std::shared_ptr<VMBootParameters> boot_params)
Expand Down
4 changes: 2 additions & 2 deletions pcsx2-qt/QtHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class EmuThread : public QThread
__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); }
Expand Down Expand Up @@ -206,9 +206,9 @@ private Q_SLOTS:
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;
Expand Down

0 comments on commit 64b6dec

Please sign in to comment.