summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2018-07-05 14:58:59 +0200
committerMartijn Coenen <maco@google.com>2018-07-09 18:11:18 +0000
commitd3ef4bf663231b348daed2cd41379853cc6d24c3 (patch)
treecf027304c66450d5899b42b16b95589a4ca94221 /core/java/android
parentce77407144346c6fad679a4297910eea07d0d601 (diff)
Move BinderProxy serialization into Java.
The BinderProxy class is not thread-safe, and all calls into it were serialized by holding gProxyLock from JNI code. More recently, we've been wanting to access BinderProxy from Java code directly, and having the lock in native complicated things. This change removes the lock in native code and adds it in the Java layer. A benefit of this change is that it reduces the scope of where a lock is held. On the flip side, we no longer have a cached BinderProxyNativeData object lying around. This means we now allocate/free a BinderProxyNativeData even if we already have a Java object lying around for the native object, which can happen quite frequently. But we deem the impact of this to be acceptable. Bug: 109888955 Test: sailfish builds, boots, proxy warnings still show Change-Id: If2f4dbe5486ec7af0ef8ea42d24ac3a4330cc05a
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/os/Binder.java41
1 files changed, 21 insertions, 20 deletions
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index ac871055dc4a..42f806c01c08 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -23,6 +23,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.SparseIntArray;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BinderCallsStats;
import com.android.internal.os.BinderInternal;
import com.android.internal.util.FastPrintWriter;
@@ -1027,19 +1028,19 @@ final class BinderProxy implements IBinder {
new ArrayList[MAIN_INDEX_SIZE];
}
- private static ProxyMap sProxyMap = new ProxyMap();
+ @GuardedBy("sProxyMap")
+ private static final ProxyMap sProxyMap = new ProxyMap();
/**
* Dump proxy debug information.
*
- * Note: this method is not thread-safe; callers must serialize with other
- * accesses to sProxyMap, in particular {@link #getInstance(long, long)}.
- *
* @hide
*/
private static void dumpProxyDebugInfo() {
if (Build.IS_DEBUGGABLE) {
- sProxyMap.dumpProxyInterfaceCounts();
+ synchronized (sProxyMap) {
+ sProxyMap.dumpProxyInterfaceCounts();
+ }
// Note that we don't call dumpPerUidProxyCounts(); this is because this
// method may be called as part of the uid limit being hit, and calling
// back into the UID tracking code would cause us to try to acquire a mutex
@@ -1049,8 +1050,6 @@ final class BinderProxy implements IBinder {
/**
* Return a BinderProxy for IBinder.
- * This method is thread-hostile! The (native) caller serializes getInstance() calls using
- * gProxyLock.
* If we previously returned a BinderProxy bp for the same iBinder, and bp is still
* in use, then we return the same bp.
*
@@ -1062,21 +1061,23 @@ final class BinderProxy implements IBinder {
*/
private static BinderProxy getInstance(long nativeData, long iBinder) {
BinderProxy result;
- try {
- result = sProxyMap.get(iBinder);
- if (result != null) {
- return result;
+ synchronized (sProxyMap) {
+ try {
+ result = sProxyMap.get(iBinder);
+ if (result != null) {
+ return result;
+ }
+ result = new BinderProxy(nativeData);
+ } catch (Throwable e) {
+ // We're throwing an exception (probably OOME); don't drop nativeData.
+ NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer,
+ nativeData);
+ throw e;
}
- result = new BinderProxy(nativeData);
- } catch (Throwable e) {
- // We're throwing an exception (probably OOME); don't drop nativeData.
- NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer,
- nativeData);
- throw e;
+ NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData);
+ // The registry now owns nativeData, even if registration threw an exception.
+ sProxyMap.set(iBinder, result);
}
- NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData);
- // The registry now owns nativeData, even if registration threw an exception.
- sProxyMap.set(iBinder, result);
return result;
}