diff options
author | Wale Ogunwale <ogunwale@google.com> | 2015-04-24 22:35:34 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-04-24 22:35:34 +0000 |
commit | 584e513952a28fb5d926fccc4ed640f48ee758d4 (patch) | |
tree | 7308ac157f39823fedccf843e74924c2b4684897 /core/java/android/app | |
parent | 169364c1e5d1a8f31ba8c85321c836c35ad57ba4 (diff) | |
parent | cc9c597dad6d99242ed2903d8760922f66223401 (diff) | |
download | frameworks_base-584e513952a28fb5d926fccc4ed640f48ee758d4.zip frameworks_base-584e513952a28fb5d926fccc4ed640f48ee758d4.tar.gz frameworks_base-584e513952a28fb5d926fccc4ed640f48ee758d4.tar.bz2 |
am cc9c597d: am d639a453: am e60077e6: Merge "Revert "[ActivityManager] Improve multi-thread access the same provider""
* commit 'cc9c597dad6d99242ed2903d8760922f66223401':
Revert "[ActivityManager] Improve multi-thread access the same provider"
Diffstat (limited to 'core/java/android/app')
-rw-r--r-- | core/java/android/app/ActivityThread.java | 102 |
1 files changed, 33 insertions, 69 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d69bdf9..9bad9bb 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -255,21 +255,18 @@ public final class ActivityThread { } } - static final class AcquiringProviderRecord { - IActivityManager.ContentProviderHolder holder; - boolean acquiring = true; - int requests = 1; - } - // The lock of mProviderMap protects the following variables. - final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap = new ArrayMap<>(); - final ArrayMap<ProviderKey, AcquiringProviderRecord> mAcquiringProviderMap = new ArrayMap<>(); - final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap = new ArrayMap<>(); - final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders = new ArrayMap<>(); - final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new ArrayMap<>(); + final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap + = new ArrayMap<ProviderKey, ProviderClientRecord>(); + final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap + = new ArrayMap<IBinder, ProviderRefCount>(); + final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders + = new ArrayMap<IBinder, ProviderClientRecord>(); + final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName + = new ArrayMap<ComponentName, ProviderClientRecord>(); final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners - = new ArrayMap<>(); + = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); final GcIdler mGcIdler = new GcIdler(); boolean mGcIdlerScheduled = false; @@ -349,7 +346,7 @@ public final class ActivityThread { } } - static final class ProviderClientRecord { + final class ProviderClientRecord { final String[] mNames; final IContentProvider mProvider; final ContentProvider mLocalProvider; @@ -4714,57 +4711,22 @@ public final class ActivityThread { public final IContentProvider acquireProvider( Context c, String auth, int userId, boolean stable) { - final ProviderKey key = new ProviderKey(auth, userId); - final IContentProvider provider = acquireExistingProvider(c, key, stable); + final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); if (provider != null) { return provider; } - AcquiringProviderRecord r; - boolean first = false; - synchronized (mAcquiringProviderMap) { - r = mAcquiringProviderMap.get(key); - if (r == null) { - r = new AcquiringProviderRecord(); - mAcquiringProviderMap.put(key, r); - first = true; - } else { - r.requests++; - } - } + // There is a possible race here. Another thread may try to acquire + // the same provider at the same time. When this happens, we want to ensure + // that the first one wins. + // Note that we cannot hold the lock while acquiring and installing the + // provider since it might take a long time to run and it could also potentially + // be re-entrant in the case where the provider is in the same process. IActivityManager.ContentProviderHolder holder = null; - if (first) { - // Multiple threads may try to acquire the same provider at the same time. - // When this happens, we only let the first one really gets provider. - // Other threads just wait for its result. - // Note that we cannot hold the lock while acquiring and installing the - // provider since it might take a long time to run and it could also potentially - // be re-entrant in the case where the provider is in the same process. - try { - holder = ActivityManagerNative.getDefault().getContentProvider( - getApplicationThread(), auth, userId, stable); - } catch (RemoteException ex) { - } - synchronized (r) { - r.holder = holder; - r.acquiring = false; - r.notifyAll(); - } - } else { - synchronized (r) { - while (r.acquiring) { - try { - r.wait(); - } catch (InterruptedException e) { - } - } - holder = r.holder; - } - } - synchronized (mAcquiringProviderMap) { - if (--r.requests == 0) { - mAcquiringProviderMap.remove(key); - } + try { + holder = ActivityManagerNative.getDefault().getContentProvider( + getApplicationThread(), auth, userId, stable); + } catch (RemoteException ex) { } if (holder == null) { Slog.e(TAG, "Failed to find provider info for " + auth); @@ -4848,12 +4810,8 @@ public final class ActivityThread { public final IContentProvider acquireExistingProvider( Context c, String auth, int userId, boolean stable) { - return acquireExistingProvider(c, new ProviderKey(auth, userId), stable); - } - - final IContentProvider acquireExistingProvider( - Context c, ProviderKey key, boolean stable) { synchronized (mProviderMap) { + final ProviderKey key = new ProviderKey(auth, userId); final ProviderClientRecord pr = mProviderMap.get(key); if (pr == null) { return null; @@ -4864,7 +4822,7 @@ public final class ActivityThread { if (!jBinder.isBinderAlive()) { // The hosting process of the provider has died; we can't // use this one. - Log.i(TAG, "Acquiring provider " + key.authority + " for user " + key.userId + Log.i(TAG, "Acquiring provider " + auth + " for user " + userId + ": existing object's process dead"); handleUnstableProviderDiedLocked(jBinder, true); return null; @@ -5186,12 +5144,18 @@ public final class ActivityThread { if (DEBUG_PROVIDER) { Slog.v(TAG, "installProvider: lost the race, updating ref count"); } - // The provider has already been installed, so we need - // to increase reference count to the existing one, but - // only if release is needed (that is, it is not running - // in the system process or local to the process). + // We need to transfer our new reference to the existing + // ref count, releasing the old one... but only if + // release is needed (that is, it is not running in the + // system process). if (!noReleaseNeeded) { incProviderRefLocked(prc, stable); + try { + ActivityManagerNative.getDefault().removeContentProvider( + holder.connection, stable); + } catch (RemoteException e) { + //do nothing content provider object is dead any way + } } } else { ProviderClientRecord client = installProviderAuthoritiesLocked( |