am 8f0e0c1f: Merge "Clean-up state if we have an exception when acquiring provider"

* commit '8f0e0c1f3d7c02dff6fe4877477af583e490e6ee':
  Clean-up state if we have an exception when acquiring provider
This commit is contained in:
Wale Ogunwale
2015-04-13 04:46:31 +00:00
committed by Android Git Automerger

View File

@@ -261,6 +261,8 @@ public final class ActivityThread {
IActivityManager.ContentProviderHolder holder; IActivityManager.ContentProviderHolder holder;
boolean acquiring = true; boolean acquiring = true;
int requests = 1; int requests = 1;
// Set if there was a runtime exception when trying to acquire the provider.
RuntimeException runtimeException = null;
} }
// The lock of mProviderMap protects the following variables. // The lock of mProviderMap protects the following variables.
@@ -4667,39 +4669,55 @@ public final class ActivityThread {
} }
IActivityManager.ContentProviderHolder holder = null; IActivityManager.ContentProviderHolder holder = null;
if (first) { try {
// Multiple threads may try to acquire the same provider at the same time. if (first) {
// When this happens, we only let the first one really gets provider. // Multiple threads may try to acquire the same provider at the same time.
// Other threads just wait for its result. // When this happens, we only let the first one really gets provider.
// Note that we cannot hold the lock while acquiring and installing the // Other threads just wait for its result.
// provider since it might take a long time to run and it could also potentially // Note that we cannot hold the lock while acquiring and installing the
// be re-entrant in the case where the provider is in the same process. // provider since it might take a long time to run and it could also potentially
try { // be re-entrant in the case where the provider is in the same process.
holder = ActivityManagerNative.getDefault().getContentProvider( holder = ActivityManagerNative.getDefault().getContentProvider(
getApplicationThread(), auth, userId, stable); getApplicationThread(), auth, userId, stable);
} catch (RemoteException ex) { } else {
} synchronized (r) {
synchronized (r) { while (r.acquiring) {
r.holder = holder; try {
r.acquiring = false; r.wait();
r.notifyAll(); } catch (InterruptedException e) {
} }
} else {
synchronized (r) {
while (r.acquiring) {
try {
r.wait();
} catch (InterruptedException e) {
} }
holder = r.holder;
} }
holder = r.holder; }
} } catch (RemoteException ex) {
} } catch (RuntimeException e) {
synchronized (mAcquiringProviderMap) { synchronized (r) {
if (--r.requests == 0) { r.runtimeException = e;
mAcquiringProviderMap.remove(key); }
} finally {
if (first) {
synchronized (r) {
r.holder = holder;
r.acquiring = false;
r.notifyAll();
}
}
synchronized (mAcquiringProviderMap) {
if (--r.requests == 0) {
mAcquiringProviderMap.remove(key);
}
}
if (r.runtimeException != null) {
// Was set when the first thread tried to acquire the provider,
// but we should make sure it is thrown for all threads trying to
// acquire the provider.
throw r.runtimeException;
} }
} }
if (holder == null) { if (holder == null) {
Slog.e(TAG, "Failed to find provider info for " + auth); Slog.e(TAG, "Failed to find provider info for " + auth);
return null; return null;