diff options
author | Matthew Williams <mjwilliams@google.com> | 2013-09-12 14:30:09 -0700 |
---|---|---|
committer | Matthew Williams <mjwilliams@google.com> | 2013-09-20 18:24:30 +0000 |
commit | ed37b93af8d06243cbddec20eef2e89cd9b3677e (patch) | |
tree | ffd0efa5868b5c5c0937bbd2b343ff222bf0cbe2 /services | |
parent | 9210bc85545f31973c957b5179e6a82d05f473c6 (diff) | |
download | frameworks_base-ed37b93af8d06243cbddec20eef2e89cd9b3677e.zip frameworks_base-ed37b93af8d06243cbddec20eef2e89cd9b3677e.tar.gz frameworks_base-ed37b93af8d06243cbddec20eef2e89cd9b3677e.tar.bz2 |
fix deadlock caused by clearAllBackoffs in SSE
ordering of locks in SyncStorageEngine#clearAllBackoffs()
introduced deadlocks.
Bug: 10751759
Bug: 10680330
Change-Id: Ief118830b6b249de0e7618b6186b4181b4f12f82
Diffstat (limited to 'services')
-rw-r--r-- | services/java/com/android/server/content/SyncManager.java | 4 | ||||
-rw-r--r-- | services/java/com/android/server/content/SyncStorageEngine.java | 41 |
2 files changed, 25 insertions, 20 deletions
diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java index 9a41166..635ba5c 100644 --- a/services/java/com/android/server/content/SyncManager.java +++ b/services/java/com/android/server/content/SyncManager.java @@ -315,7 +315,9 @@ public class SyncManager { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Reconnection detected: clearing all backoffs"); } - mSyncStorageEngine.clearAllBackoffs(mSyncQueue); + synchronized(mSyncQueue) { + mSyncStorageEngine.clearAllBackoffsLocked(mSyncQueue); + } } sendCheckAlarmsMessage(); } diff --git a/services/java/com/android/server/content/SyncStorageEngine.java b/services/java/com/android/server/content/SyncStorageEngine.java index 1b9ed98..d51c2d7 100644 --- a/services/java/com/android/server/content/SyncStorageEngine.java +++ b/services/java/com/android/server/content/SyncStorageEngine.java @@ -710,28 +710,31 @@ public class SyncStorageEngine extends Handler { } } - public void clearAllBackoffs(SyncQueue syncQueue) { + /** + * Callers of this function need to hold a lock for syncQueue object passed in. Bear in mind + * this function grabs the lock for {@link #mAuthorities} + * @param syncQueue queue containing pending sync operations. + */ + public void clearAllBackoffsLocked(SyncQueue syncQueue) { boolean changed = false; synchronized (mAuthorities) { - synchronized (syncQueue) { - for (AccountInfo accountInfo : mAccounts.values()) { - for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { - if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE - || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { - if (DEBUG) { - Log.v(TAG, "clearAllBackoffs:" - + " authority:" + authorityInfo.authority - + " account:" + accountInfo.accountAndUser.account.name - + " user:" + accountInfo.accountAndUser.userId - + " backoffTime was: " + authorityInfo.backoffTime - + " backoffDelay was: " + authorityInfo.backoffDelay); - } - authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE; - authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; - syncQueue.onBackoffChanged(accountInfo.accountAndUser.account, - accountInfo.accountAndUser.userId, authorityInfo.authority, 0); - changed = true; + for (AccountInfo accountInfo : mAccounts.values()) { + for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { + if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE + || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { + if (DEBUG) { + Log.v(TAG, "clearAllBackoffs:" + + " authority:" + authorityInfo.authority + + " account:" + accountInfo.accountAndUser.account.name + + " user:" + accountInfo.accountAndUser.userId + + " backoffTime was: " + authorityInfo.backoffTime + + " backoffDelay was: " + authorityInfo.backoffDelay); } + authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE; + authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; + syncQueue.onBackoffChanged(accountInfo.accountAndUser.account, + accountInfo.accountAndUser.userId, authorityInfo.authority, 0); + changed = true; } } } |