Merge pull request #10435 from AdmiralCurtiss/savestate-crash
Core/State: Add some multithreading protections.
This commit is contained in:
commit
9214174bb3
|
@ -64,12 +64,13 @@ static AfterLoadCallbackFunc s_on_after_load_callback;
|
|||
// Temporary undo state buffer
|
||||
static std::vector<u8> g_undo_load_buffer;
|
||||
static std::vector<u8> g_current_buffer;
|
||||
static bool s_load_or_save_in_progress;
|
||||
static std::mutex s_load_or_save_in_progress_mutex;
|
||||
|
||||
static std::mutex g_cs_undo_load_buffer;
|
||||
static std::mutex g_cs_current_buffer;
|
||||
static Common::Event g_compressAndDumpStateSyncEvent;
|
||||
|
||||
static std::recursive_mutex g_save_thread_mutex;
|
||||
static std::thread g_save_thread;
|
||||
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
|
@ -403,11 +404,10 @@ static void CompressAndDumpState(CompressAndDumpState_args save_args)
|
|||
|
||||
void SaveAs(const std::string& filename, bool wait)
|
||||
{
|
||||
if (s_load_or_save_in_progress)
|
||||
std::unique_lock lk(s_load_or_save_in_progress_mutex, std::try_to_lock);
|
||||
if (!lk)
|
||||
return;
|
||||
|
||||
s_load_or_save_in_progress = true;
|
||||
|
||||
Core::RunOnCPUThread(
|
||||
[&] {
|
||||
// Measure the size of the buffer.
|
||||
|
@ -435,8 +435,12 @@ void SaveAs(const std::string& filename, bool wait)
|
|||
save_args.filename = filename;
|
||||
save_args.wait = wait;
|
||||
|
||||
Flush();
|
||||
g_save_thread = std::thread(CompressAndDumpState, save_args);
|
||||
{
|
||||
std::lock_guard lk(g_save_thread_mutex);
|
||||
Flush();
|
||||
g_save_thread = std::thread(CompressAndDumpState, save_args);
|
||||
}
|
||||
|
||||
g_compressAndDumpStateSyncEvent.Wait();
|
||||
}
|
||||
else
|
||||
|
@ -446,8 +450,6 @@ void SaveAs(const std::string& filename, bool wait)
|
|||
}
|
||||
},
|
||||
true);
|
||||
|
||||
s_load_or_save_in_progress = false;
|
||||
}
|
||||
|
||||
bool ReadHeader(const std::string& filename, StateHeader& header)
|
||||
|
@ -550,17 +552,18 @@ static void LoadFileStateData(const std::string& filename, std::vector<u8>& ret_
|
|||
|
||||
void LoadAs(const std::string& filename)
|
||||
{
|
||||
if (!Core::IsRunning() || s_load_or_save_in_progress)
|
||||
{
|
||||
if (!Core::IsRunning())
|
||||
return;
|
||||
}
|
||||
else if (NetPlay::IsNetPlayRunning())
|
||||
|
||||
if (NetPlay::IsNetPlayRunning())
|
||||
{
|
||||
OSD::AddMessage("Loading savestates is disabled in Netplay to prevent desyncs");
|
||||
return;
|
||||
}
|
||||
|
||||
s_load_or_save_in_progress = true;
|
||||
std::unique_lock lk(s_load_or_save_in_progress_mutex, std::try_to_lock);
|
||||
if (!lk)
|
||||
return;
|
||||
|
||||
Core::RunOnCPUThread(
|
||||
[&] {
|
||||
|
@ -617,8 +620,6 @@ void LoadAs(const std::string& filename)
|
|||
s_on_after_load_callback();
|
||||
},
|
||||
true);
|
||||
|
||||
s_load_or_save_in_progress = false;
|
||||
}
|
||||
|
||||
void SetOnAfterLoadCallback(AfterLoadCallbackFunc callback)
|
||||
|
@ -699,6 +700,8 @@ void SaveFirstSaved()
|
|||
|
||||
void Flush()
|
||||
{
|
||||
std::lock_guard lk(g_save_thread_mutex);
|
||||
|
||||
// If already saving state, wait for it to finish
|
||||
if (g_save_thread.joinable())
|
||||
g_save_thread.join();
|
||||
|
|
Loading…
Reference in New Issue