diff options
author | Amith Yamasani <yamasani@google.com> | 2013-10-03 10:34:58 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2013-10-03 15:10:52 -0700 |
commit | 0c19bf524493f2feedf442d390c878fd1ca66d7b (patch) | |
tree | f8219ac2a7410c66301c47eec8f1b14c8d931ef7 /services | |
parent | d585f95406f8b12e36ca436faea7113ecd8704fd (diff) | |
download | frameworks_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')
-rw-r--r-- | services/java/com/android/server/accounts/AccountManagerService.java | 42 |
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. |