summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server
diff options
context:
space:
mode:
authorAmith Yamasani <yamasani@google.com>2013-10-03 10:34:58 -0700
committerAmith Yamasani <yamasani@google.com>2013-10-03 15:10:52 -0700
commit0c19bf524493f2feedf442d390c878fd1ca66d7b (patch)
treef8219ac2a7410c66301c47eec8f1b14c8d931ef7 /services/java/com/android/server
parentd585f95406f8b12e36ca436faea7113ecd8704fd (diff)
downloadframeworks_base-0c19bf524493f2feedf442d390c878fd1ca66d7b.zip
frameworks_base-0c19bf524493f2feedf442d390c878fd1ca66d7b.tar.gz
frameworks_base-0c19bf524493f2feedf442d390c878fd1ca66d7b.tar.bz2
Avoid deadlock between mUsers and cacheLock
Should fix the occasional deadlock that ends up killing the system process via Watchdog. Bug: 11033281 Change-Id: Ie9cec0b6e2bd44bb03848b04aec5f9bd04ee74d6
Diffstat (limited to 'services/java/com/android/server')
-rw-r--r--services/java/com/android/server/accounts/AccountManagerService.java42
1 files changed, 20 insertions, 22 deletions
diff --git a/services/java/com/android/server/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java
index dd9ae4c..cc43a9c 100644
--- a/services/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/java/com/android/server/accounts/AccountManagerService.java
@@ -293,17 +293,16 @@ public class AccountManagerService
return mUserManager;
}
- private UserAccounts initUser(int userId) {
- synchronized (mUsers) {
- UserAccounts accounts = mUsers.get(userId);
- if (accounts == null) {
- accounts = new UserAccounts(mContext, userId);
- mUsers.append(userId, accounts);
- purgeOldGrants(accounts);
- validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
- }
- return accounts;
+ /* Caller should lock mUsers */
+ private UserAccounts initUserLocked(int userId) {
+ UserAccounts accounts = mUsers.get(userId);
+ if (accounts == null) {
+ accounts = new UserAccounts(mContext, userId);
+ mUsers.append(userId, accounts);
+ purgeOldGrants(accounts);
+ validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
}
+ return accounts;
}
private void purgeOldGrantsAll() {
@@ -427,7 +426,7 @@ public class AccountManagerService
synchronized (mUsers) {
UserAccounts accounts = mUsers.get(userId);
if (accounts == null) {
- accounts = initUser(userId);
+ accounts = initUserLocked(userId);
mUsers.append(userId, accounts);
}
return accounts;
@@ -1798,16 +1797,14 @@ public class AccountManagerService
private AccountAndUser[] getAccounts(int[] userIds) {
final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList();
- synchronized (mUsers) {
- for (int userId : userIds) {
- UserAccounts userAccounts = getUserAccounts(userId);
- if (userAccounts == null) continue;
- synchronized (userAccounts.cacheLock) {
- Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
- Binder.getCallingUid(), null);
- for (int a = 0; a < accounts.length; a++) {
- runningAccounts.add(new AccountAndUser(accounts[a], userId));
- }
+ for (int userId : userIds) {
+ UserAccounts userAccounts = getUserAccounts(userId);
+ if (userAccounts == null) continue;
+ synchronized (userAccounts.cacheLock) {
+ Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
+ Binder.getCallingUid(), null);
+ for (int a = 0; a < accounts.length; a++) {
+ runningAccounts.add(new AccountAndUser(accounts[a], userId));
}
}
}
@@ -2858,7 +2855,8 @@ public class AccountManagerService
|| callingUid == Process.myUid()) {
return unfiltered;
}
- if (mUserManager.getUserInfo(userAccounts.userId).isRestricted()) {
+ UserInfo user = mUserManager.getUserInfo(userAccounts.userId);
+ if (user != null && user.isRestricted()) {
String[] packages = mPackageManager.getPackagesForUid(callingUid);
// If any of the packages is a white listed package, return the full set,
// otherwise return non-shared accounts only.