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:
parent
138adc28d7
commit
09ab139407
|
@ -908,15 +908,20 @@ void Emulator::start()
|
||||||
bool Emulator::checkStatus(bool wait)
|
bool Emulator::checkStatus(bool wait)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
std::unique_lock<std::mutex> lock(mutex);
|
||||||
if (threadResult.valid())
|
if (threadResult.valid())
|
||||||
{
|
{
|
||||||
if (!wait)
|
lock.unlock();
|
||||||
{
|
auto localResult = threadResult;
|
||||||
auto result = threadResult.wait_for(std::chrono::seconds(0));
|
if (wait) {
|
||||||
|
localResult.wait();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto result = localResult.wait_for(std::chrono::seconds(0));
|
||||||
if (result == std::future_status::timeout)
|
if (result == std::future_status::timeout)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
lock.lock();
|
||||||
threadResult.get();
|
threadResult.get();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -179,7 +179,7 @@ private:
|
||||||
Terminated,
|
Terminated,
|
||||||
};
|
};
|
||||||
State state = Uninitialized;
|
State state = Uninitialized;
|
||||||
std::future<void> threadResult;
|
std::shared_future<void> threadResult;
|
||||||
bool resetRequested = false;
|
bool resetRequested = false;
|
||||||
bool singleStep = false;
|
bool singleStep = false;
|
||||||
u64 startTime = 0;
|
u64 startTime = 0;
|
||||||
|
|
Loading…
Reference in New Issue