From a2300c1a968037553dbafb1fe9651e0496156964 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:35:24 +0100 Subject: [PATCH] fix crashes when signalling a event thats not created yet. this caused a crash after installing a game if the games menu wasn't init. the same would happen if the games menu signalled the save menu. --- sphaira/source/ui/menus/filebrowser.cpp | 9 +++++---- sphaira/source/ui/menus/game_menu.cpp | 13 ++++++++----- sphaira/source/ui/menus/homebrew.cpp | 9 +++++---- sphaira/source/ui/menus/save_menu.cpp | 9 ++++----- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index 0ea914a..e931f15 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -73,7 +73,7 @@ private: SidebarEntryFilePicker* m_icon{}; }; -constinit UEvent g_change_uevent; +std::atomic_bool g_change_signalled{}; constexpr FsEntry FS_ENTRY_DEFAULT{ "microSD card", "/", FsType::Sd, FsEntryFlag_Assoc | FsEntryFlag_IsSd, @@ -418,7 +418,7 @@ auto IsExtension(std::string_view ext, std::span list) - } void SignalChange() { - ueventSignal(&g_change_uevent); + g_change_signalled = true; } FsView::FsView(Base* menu, const std::shared_ptr& fs, const fs::FsPath& path, const FsEntry& entry, ViewSide side) : m_menu{menu}, m_side{side} { @@ -1026,6 +1026,7 @@ auto FsView::Scan(fs::FsPath new_path, bool is_walk_up) -> Result { m_previous_highlighted_file.emplace_back(f); } + g_change_signalled = false; m_path = new_path; m_entries.clear(); m_entries_index.clear(); @@ -1937,7 +1938,8 @@ Base::Base(const std::shared_ptr& fs, const FsEntry& fs_entry, const fs: } void Base::Update(Controller* controller, TouchInfo* touch) { - if (R_SUCCEEDED(waitSingle(waiterForUEvent(&g_change_uevent), 0))) { + if (g_change_signalled.exchange(false)) { + if (IsSplitScreen()) { view_left->SortAndFindLastFile(true); view_right->SortAndFindLastFile(true); @@ -2278,7 +2280,6 @@ void Base::Init(const std::shared_ptr& fs, const FsEntry& fs_entry, cons view_left = std::make_unique(this, fs, path, fs_entry, ViewSide::Left); view = view_left.get(); - ueventCreate(&g_change_uevent, true); } void MountFsHelper(const std::shared_ptr& fs, const fs::FsPath& name) { diff --git a/sphaira/source/ui/menus/game_menu.cpp b/sphaira/source/ui/menus/game_menu.cpp index 44800f6..3657aa2 100644 --- a/sphaira/source/ui/menus/game_menu.cpp +++ b/sphaira/source/ui/menus/game_menu.cpp @@ -36,7 +36,7 @@ namespace sphaira::ui::menu::game { namespace { -constinit UEvent g_change_uevent; +std::atomic_bool g_change_signalled{}; struct NspSource final : dump::BaseSource { NspSource(const std::vector& entries) : m_entries{entries} { @@ -273,7 +273,7 @@ Result NspEntry::Read(void* buf, s64 off, s64 size, u64* bytes_read) { } void SignalChange() { - ueventSignal(&g_change_uevent); + g_change_signalled = true; } Menu::Menu(u32 flags) : grid::Menu{"Games"_i18n, flags} { @@ -461,7 +461,6 @@ Menu::Menu(u32 flags) : grid::Menu{"Games"_i18n, flags} { fsOpenGameCardDetectionEventNotifier(std::addressof(m_gc_event_notifier)); fsEventNotifierGetEventHandle(std::addressof(m_gc_event_notifier), std::addressof(m_gc_event), true); - ueventCreate(&g_change_uevent, true); } Menu::~Menu() { @@ -476,8 +475,11 @@ Menu::~Menu() { } void Menu::Update(Controller* controller, TouchInfo* touch) { - s32 wait_dummy_idx; - if (R_SUCCEEDED(waitMulti(&wait_dummy_idx, 0, waiterForEvent(&m_gc_event), waiterForUEvent(&g_change_uevent)))) { + if (g_change_signalled.exchange(false)) { + m_dirty = true; + } + + if (R_SUCCEEDED(eventWait(&m_gc_event, 0))) { m_dirty = true; } @@ -569,6 +571,7 @@ void Menu::ScanHomebrew() { FreeEntries(); m_entries.reserve(ENTRY_CHUNK_COUNT); + g_change_signalled = false; std::vector record_list(ENTRY_CHUNK_COUNT); s32 offset{}; diff --git a/sphaira/source/ui/menus/homebrew.cpp b/sphaira/source/ui/menus/homebrew.cpp index 092d515..258e89f 100644 --- a/sphaira/source/ui/menus/homebrew.cpp +++ b/sphaira/source/ui/menus/homebrew.cpp @@ -27,7 +27,7 @@ namespace sphaira::ui::menu::homebrew { namespace { Menu* g_menu{}; -constinit UEvent g_change_uevent; +std::atomic_bool g_change_signalled{}; auto GenerateStarPath(const fs::FsPath& nro_path) -> fs::FsPath { fs::FsPath out{}; @@ -44,7 +44,7 @@ void FreeEntry(NVGcontext* vg, NroEntry& e) { } // namespace void SignalChange() { - ueventSignal(&g_change_uevent); + g_change_signalled = true; } auto GetNroEntries() -> std::span { @@ -68,7 +68,6 @@ Menu::Menu() : grid::Menu{"Homebrew"_i18n, MenuFlag_Tab} { ); OnLayoutChange(); - ueventCreate(&g_change_uevent, true); } Menu::~Menu() { @@ -77,7 +76,7 @@ Menu::~Menu() { } void Menu::Update(Controller* controller, TouchInfo* touch) { - if (R_SUCCEEDED(waitSingle(waiterForUEvent(&g_change_uevent), 0))) { + if (g_change_signalled.exchange(false)) { m_dirty = true; } @@ -198,7 +197,9 @@ void Menu::InstallHomebrew() { } void Menu::ScanHomebrew() { + g_change_signalled = false; FreeEntries(); + { SCOPED_TIMESTAMP("nro scan"); nro_scan("/switch", m_entries); diff --git a/sphaira/source/ui/menus/save_menu.cpp b/sphaira/source/ui/menus/save_menu.cpp index a351d72..0b048d2 100644 --- a/sphaira/source/ui/menus/save_menu.cpp +++ b/sphaira/source/ui/menus/save_menu.cpp @@ -40,7 +40,7 @@ constexpr u32 NX_SAVE_META_MAGIC = 0x4A4B5356; // JKSV constexpr u32 NX_SAVE_META_VERSION = 1; constexpr const char* NX_SAVE_META_NAME = ".nx_save_meta.bin"; -constinit UEvent g_change_uevent; +std::atomic_bool g_change_signalled{}; struct DumpSource final : dump::BaseSource { DumpSource(std::span> entries, std::span paths) @@ -319,7 +319,7 @@ void FreeEntry(NVGcontext* vg, Entry& e) { } // namespace void SignalChange() { - ueventSignal(&g_change_uevent); + g_change_signalled = true; } Menu::Menu(u32 flags) : grid::Menu{"Saves"_i18n, flags} { @@ -388,7 +388,6 @@ Menu::Menu(u32 flags) : grid::Menu{"Saves"_i18n, flags} { } title::Init(); - ueventCreate(&g_change_uevent, true); } Menu::~Menu() { @@ -399,7 +398,7 @@ Menu::~Menu() { } void Menu::Update(Controller* controller, TouchInfo* touch) { - if (R_SUCCEEDED(waitSingle(waiterForUEvent(&g_change_uevent), 0))) { + if (g_change_signalled.exchange(false)) { m_dirty = true; } @@ -508,9 +507,9 @@ void Menu::ScanHomebrew() { constexpr auto ENTRY_CHUNK_COUNT = 1000; TimeStamp ts; + g_change_signalled = false; FreeEntries(); ClearSelection(); - ueventClear(&g_change_uevent); m_entries.reserve(ENTRY_CHUNK_COUNT); m_is_reversed = false; m_dirty = false;