Merge "Fix Deadlock Issue On AppFuseBridge" into rvc-dev am: a27544861b am: 4537a78288 am: 03cbfcdc5a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11894161

Change-Id: I621d737d0da34e547b617bf5d26540141fdc9207
This commit is contained in:
Narayan Kamath
2020-06-18 11:05:25 +00:00
committed by Automerger Merge Worker
2 changed files with 30 additions and 0 deletions

View File

@@ -56,6 +56,15 @@ public class AppFuseBridge implements Runnable {
public ParcelFileDescriptor addBridge(MountScope mountScope)
throws FuseUnavailableMountException, NativeDaemonConnectorException {
/*
** Dead Lock between Java lock (AppFuseBridge.java) and Native lock (FuseBridgeLoop.cc)
**
** (Thread A) Got Java lock (addBrdige) -> Try to get Native lock (native_add_brdige)
** (Thread B) Got Native lock (FuseBrdigeLoop.start) -> Try to get Java lock (onClosed)
**
** Guarantee the lock order (native lock -> java lock) when adding Bridge.
*/
native_lock();
try {
synchronized (this) {
Preconditions.checkArgument(mScopes.indexOfKey(mountScope.mountId) < 0);
@@ -73,6 +82,7 @@ public class AppFuseBridge implements Runnable {
return result;
}
} finally {
native_unlock();
IoUtils.closeQuietly(mountScope);
}
}
@@ -159,4 +169,6 @@ public class AppFuseBridge implements Runnable {
private native void native_delete(long loop);
private native void native_start_loop(long loop);
private native int native_add_bridge(long loop, int mountId, int deviceId);
private native void native_lock();
private native void native_unlock();
}

View File

@@ -123,6 +123,14 @@ jint com_android_server_storage_AppFuseBridge_add_bridge(
return proxyFd[1].release();
}
void com_android_server_storage_AppFuseBridge_lock(JNIEnv* env, jobject self) {
fuse::FuseBridgeLoop::Lock();
}
void com_android_server_storage_AppFuseBridge_unlock(JNIEnv* env, jobject self) {
fuse::FuseBridgeLoop::Unlock();
}
const JNINativeMethod methods[] = {
{
"native_new",
@@ -143,6 +151,16 @@ const JNINativeMethod methods[] = {
"native_add_bridge",
"(JII)I",
reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_add_bridge)
},
{
"native_lock",
"()V",
reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_lock)
},
{
"native_unlock",
"()V",
reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_unlock)
}
};