Android: Fix race condition when exiting emulation

The main activity loads settings essentially as soon as it
starts, in order to determine which tab to show. If the process
of stopping emulation has not finished at this point, a race
condition may be triggered where two IOS kernels are created
at once due to the emulation thread loading or saving the
SYSCONF while the GUI thread is loading the SYSCONF. To fix
this, we can wait for emulation to fully end before returning.

Because this race condition is hard to reproduce, I have not
been able to test that this actually fixes the race condition,
or even that the cause of the race condition is exactly what I
believe it is. But I am relatively confident.
This commit is contained in:
JosJuice 2020-07-22 22:26:20 +02:00
parent 9c19309a03
commit 003696fd78
1 changed files with 14 additions and 3 deletions

View File

@ -74,6 +74,7 @@ IniFile s_ini;
// sequentially for access.
std::mutex s_host_identity_lock;
Common::Event s_update_main_frame_event;
Common::Event s_emulation_end_event;
bool s_have_wm_user_stop = false;
} // Anonymous namespace
@ -282,9 +283,17 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulati
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv* env,
jobject obj)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
Core::Stop();
s_update_main_frame_event.Set(); // Kick the waiting event
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
s_emulation_end_event.Reset();
Core::Stop();
// Kick the waiting event
s_update_main_frame_event.Set();
}
// Wait for shutdown, to avoid accessing the config at the same time as the shutdown code
s_emulation_end_event.Wait();
}
JNIEXPORT void JNICALL
@ -598,6 +607,8 @@ static void Run(JNIEnv* env, const std::vector<std::string>& paths,
ANativeWindow_release(s_surf);
s_surf = nullptr;
}
s_emulation_end_event.Set();
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run___3Ljava_lang_String_2(