diff options
| -rw-r--r-- | services/core/java/com/android/server/storage/AppFuseBridge.java | 12 | ||||
| -rw-r--r-- | services/core/jni/com_android_server_storage_AppFuseBridge.cpp | 18 |
2 files changed, 30 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/storage/AppFuseBridge.java b/services/core/java/com/android/server/storage/AppFuseBridge.java index 9d6a64701e85..b00540fd2a52 100644 --- a/services/core/java/com/android/server/storage/AppFuseBridge.java +++ b/services/core/java/com/android/server/storage/AppFuseBridge.java @@ -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(); } diff --git a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp index e51963340ae1..20210abd0ea8 100644 --- a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp +++ b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp @@ -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) } }; |