Merge pull request #12919 from JosJuice/set-background-execution-allowed-crash

Fix AchievementManager::SetBackgroundExecutionAllowed crash
This commit is contained in:
Admiral H. Curtiss 2024-07-08 01:13:25 +02:00 committed by GitHub
commit 01a2cf8db9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 7 deletions

View File

@ -196,7 +196,12 @@ bool AchievementManager::IsGameLoaded() const
void AchievementManager::SetBackgroundExecutionAllowed(bool allowed) void AchievementManager::SetBackgroundExecutionAllowed(bool allowed)
{ {
m_background_execution_allowed = allowed; m_background_execution_allowed = allowed;
if (allowed && Core::GetState(*AchievementManager::GetInstance().m_system) == Core::State::Paused)
Core::System* system = m_system.load(std::memory_order_acquire);
if (!system)
return;
if (allowed && Core::GetState(*system) == Core::State::Paused)
DoIdle(); DoIdle();
} }
@ -271,7 +276,8 @@ void AchievementManager::DoFrame()
std::lock_guard lg{m_lock}; std::lock_guard lg{m_lock};
rc_client_do_frame(m_client); rc_client_do_frame(m_client);
} }
if (!m_system) Core::System* system = m_system.load(std::memory_order_acquire);
if (!system)
return; return;
auto current_time = std::chrono::steady_clock::now(); auto current_time = std::chrono::steady_clock::now();
if (current_time - m_last_rp_time > std::chrono::seconds{10}) if (current_time - m_last_rp_time > std::chrono::seconds{10})
@ -309,7 +315,8 @@ void AchievementManager::DoIdle()
Common::SleepCurrentThread(1000); Common::SleepCurrentThread(1000);
{ {
std::lock_guard lg{m_lock}; std::lock_guard lg{m_lock};
if (!m_system || Core::GetState(*m_system) != Core::State::Paused) Core::System* system = m_system.load(std::memory_order_acquire);
if (!system || Core::GetState(*system) != Core::State::Paused)
return; return;
if (!m_background_execution_allowed) if (!m_background_execution_allowed)
return; return;
@ -320,7 +327,7 @@ void AchievementManager::DoIdle()
// needs to be on host or CPU thread to access memory. // needs to be on host or CPU thread to access memory.
Core::QueueHostJob([this](Core::System& system) { Core::QueueHostJob([this](Core::System& system) {
std::lock_guard lg{m_lock}; std::lock_guard lg{m_lock};
if (!m_system || Core::GetState(*m_system) != Core::State::Paused) if (Core::GetState(system) != Core::State::Paused)
return; return;
if (!m_background_execution_allowed) if (!m_background_execution_allowed)
return; return;
@ -559,7 +566,7 @@ void AchievementManager::CloseGame()
m_queue.Cancel(); m_queue.Cancel();
m_image_queue.Cancel(); m_image_queue.Cancel();
rc_client_unload_game(m_client); rc_client_unload_game(m_client);
m_system = nullptr; m_system.store(nullptr, std::memory_order_release);
if (Config::Get(Config::RA_DISCORD_PRESENCE_ENABLED)) if (Config::Get(Config::RA_DISCORD_PRESENCE_ENABLED))
Discord::UpdateDiscordPresence(); Discord::UpdateDiscordPresence();
INFO_LOG_FMT(ACHIEVEMENTS, "Game closed."); INFO_LOG_FMT(ACHIEVEMENTS, "Game closed.");
@ -819,7 +826,7 @@ void AchievementManager::LoadGameCallback(int result, const char* error_message,
rc_client_set_read_memory_function(instance.m_client, MemoryPeeker); rc_client_set_read_memory_function(instance.m_client, MemoryPeeker);
instance.m_display_welcome_message = true; instance.m_display_welcome_message = true;
instance.FetchGameBadges(); instance.FetchGameBadges();
instance.m_system = &Core::System::GetInstance(); instance.m_system.store(&Core::System::GetInstance(), std::memory_order_release);
instance.m_update_callback({.all = true}); instance.m_update_callback({.all = true});
// Set this to a value that will immediately trigger RP // Set this to a value that will immediately trigger RP
instance.m_last_rp_time = std::chrono::steady_clock::now() - std::chrono::minutes{2}; instance.m_last_rp_time = std::chrono::steady_clock::now() - std::chrono::minutes{2};

View File

@ -5,6 +5,7 @@
#ifdef USE_RETRO_ACHIEVEMENTS #ifdef USE_RETRO_ACHIEVEMENTS
#include <array> #include <array>
#include <atomic>
#include <chrono> #include <chrono>
#include <ctime> #include <ctime>
#include <functional> #include <functional>
@ -204,7 +205,7 @@ private:
rc_runtime_t m_runtime{}; rc_runtime_t m_runtime{};
rc_client_t* m_client{}; rc_client_t* m_client{};
Core::System* m_system{}; std::atomic<Core::System*> m_system{};
bool m_is_runtime_initialized = false; bool m_is_runtime_initialized = false;
UpdateCallback m_update_callback = [](const UpdatedItems&) {}; UpdateCallback m_update_callback = [](const UpdatedItems&) {};
std::unique_ptr<DiscIO::Volume> m_loading_volume; std::unique_ptr<DiscIO::Volume> m_loading_volume;