Android: Fix race condition in displayAlertMsg
It was possible for sAlertMessageLock.notify() to be called before sAlertMessageLock.wait(), causing Dolphin to deadlock. In particular, this was guaranteed to happen if displayAlertMsg was called from the UI thread while the emulation activity is being destroyed, because runOnUiThread runs the passed-in anonymous function immediately when called from the UI thread. By replacing Object.wait/Object.notify with Semaphore.acquire/ Semaphore.release, it no longer matters what order the methods are called in.
This commit is contained in:
parent
4312840a4b
commit
9ca9d073df
|
@ -21,6 +21,7 @@ import org.dolphinemu.dolphinemu.utils.Log;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class which contains methods that interact
|
* Class which contains methods that interact
|
||||||
|
@ -28,7 +29,7 @@ import java.util.LinkedHashMap;
|
||||||
*/
|
*/
|
||||||
public final class NativeLibrary
|
public final class NativeLibrary
|
||||||
{
|
{
|
||||||
private static final Object sAlertMessageLock = new Object();
|
private static final Semaphore sAlertMessageSemaphore = new Semaphore(0);
|
||||||
private static boolean sIsShowingAlertMessage = false;
|
private static boolean sIsShowingAlertMessage = false;
|
||||||
|
|
||||||
private static WeakReference<EmulationActivity> sEmulationActivity = new WeakReference<>(null);
|
private static WeakReference<EmulationActivity> sEmulationActivity = new WeakReference<>(null);
|
||||||
|
@ -492,15 +493,12 @@ public final class NativeLibrary
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for the lock to notify that it is complete.
|
// Wait for the lock to notify that it is complete.
|
||||||
synchronized (sAlertMessageLock)
|
try
|
||||||
|
{
|
||||||
|
sAlertMessageSemaphore.acquire();
|
||||||
|
}
|
||||||
|
catch (InterruptedException ignored)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
sAlertMessageLock.wait();
|
|
||||||
}
|
|
||||||
catch (Exception ignored)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yesNo)
|
if (yesNo)
|
||||||
|
@ -520,10 +518,7 @@ public final class NativeLibrary
|
||||||
|
|
||||||
public static void NotifyAlertMessageLock()
|
public static void NotifyAlertMessageLock()
|
||||||
{
|
{
|
||||||
synchronized (sAlertMessageLock)
|
sAlertMessageSemaphore.release();
|
||||||
{
|
|
||||||
sAlertMessageLock.notify();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setEmulationActivity(EmulationActivity emulationActivity)
|
public static void setEmulationActivity(EmulationActivity emulationActivity)
|
||||||
|
|
Loading…
Reference in New Issue