diff options
| author | Martijn Coenen <maco@google.com> | 2018-07-05 14:58:59 +0200 |
|---|---|---|
| committer | Martijn Coenen <maco@google.com> | 2018-07-09 18:11:18 +0000 |
| commit | d3ef4bf663231b348daed2cd41379853cc6d24c3 (patch) | |
| tree | cf027304c66450d5899b42b16b95589a4ca94221 /core/java/android | |
| parent | ce77407144346c6fad679a4297910eea07d0d601 (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.java | 41 |
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; } |
