android: deadlock when Emulator::checkStatus is called concurrently

If checkStatus(wait = true) is called, any other thread will be blocked
even when calling with wait = false since the mutex is locked. This
happens on Android when JNIdc.rendinitNative(null) is called by the app
main thread.
Use a shared_future instead and unlock the mutex before waiting.
This commit is contained in:
Flyinghead 2024-08-15 11:55:07 +02:00
parent 138adc28d7
commit 09ab139407
2 changed files with 10 additions and 5 deletions

View File

@ -908,15 +908,20 @@ void Emulator::start()
bool Emulator::checkStatus(bool wait)
{
try {
const std::lock_guard<std::mutex> lock(mutex);
std::unique_lock<std::mutex> lock(mutex);
if (threadResult.valid())
{
if (!wait)
{
auto result = threadResult.wait_for(std::chrono::seconds(0));
lock.unlock();
auto localResult = threadResult;
if (wait) {
localResult.wait();
}
else {
auto result = localResult.wait_for(std::chrono::seconds(0));
if (result == std::future_status::timeout)
return true;
}
lock.lock();
threadResult.get();
}
return false;

View File

@ -179,7 +179,7 @@ private:
Terminated,
};
State state = Uninitialized;
std::future<void> threadResult;
std::shared_future<void> threadResult;
bool resetRequested = false;
bool singleStep = false;
u64 startTime = 0;