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:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user