Merge "Fix Deadlock Issue On AppFuseBridge" into rvc-dev am: a27544861b am: 4537a78288
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11894161 Change-Id: I0ddcfcbb3d9ba2284ca483dbc4db7e14c9d0cc10
This commit is contained in:
@@ -56,6 +56,15 @@ public class AppFuseBridge implements Runnable {
|
|||||||
|
|
||||||
public ParcelFileDescriptor addBridge(MountScope mountScope)
|
public ParcelFileDescriptor addBridge(MountScope mountScope)
|
||||||
throws FuseUnavailableMountException, NativeDaemonConnectorException {
|
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 {
|
try {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Preconditions.checkArgument(mScopes.indexOfKey(mountScope.mountId) < 0);
|
Preconditions.checkArgument(mScopes.indexOfKey(mountScope.mountId) < 0);
|
||||||
@@ -73,6 +82,7 @@ public class AppFuseBridge implements Runnable {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
native_unlock();
|
||||||
IoUtils.closeQuietly(mountScope);
|
IoUtils.closeQuietly(mountScope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,4 +169,6 @@ public class AppFuseBridge implements Runnable {
|
|||||||
private native void native_delete(long loop);
|
private native void native_delete(long loop);
|
||||||
private native void native_start_loop(long loop);
|
private native void native_start_loop(long loop);
|
||||||
private native int native_add_bridge(long loop, int mountId, int deviceId);
|
private native int native_add_bridge(long loop, int mountId, int deviceId);
|
||||||
|
private native void native_lock();
|
||||||
|
private native void native_unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,6 +123,14 @@ jint com_android_server_storage_AppFuseBridge_add_bridge(
|
|||||||
return proxyFd[1].release();
|
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[] = {
|
const JNINativeMethod methods[] = {
|
||||||
{
|
{
|
||||||
"native_new",
|
"native_new",
|
||||||
@@ -143,6 +151,16 @@ const JNINativeMethod methods[] = {
|
|||||||
"native_add_bridge",
|
"native_add_bridge",
|
||||||
"(JII)I",
|
"(JII)I",
|
||||||
reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_add_bridge)
|
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)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user