Fix AchievementManager::SetBackgroundExecutionAllowed crash
We mustn't use m_system when it is nullptr. This was causing Dolphin to crash on Android whenever an activity was recreated or resumed while emulation is running, which is super common.
This commit is contained in:
parent
02e1b94149
commit
95e2064099
|
@ -166,7 +166,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +246,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})
|
||||||
|
@ -279,7 +285,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;
|
||||||
|
@ -290,7 +297,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;
|
||||||
|
@ -487,7 +494,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.");
|
||||||
|
@ -747,7 +754,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};
|
||||||
|
|
|
@ -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>
|
||||||
|
@ -189,7 +190,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;
|
||||||
|
|
Loading…
Reference in New Issue