diff options
author | lwan89x <liangx.wang@intel.com> | 2014-09-24 18:27:49 +0800 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2015-11-07 05:40:43 -0800 |
commit | 1bb0a456e10d3de863b9637ae914dd51e06c76c5 (patch) | |
tree | c31b2c5d618352c971fd41a38eba0ccad268d1cf /services/backup/java | |
parent | 3d4374ef467d0f610b9bf1e9cacf0ca44f4d09ef (diff) | |
download | frameworks_base-1bb0a456e10d3de863b9637ae914dd51e06c76c5.zip frameworks_base-1bb0a456e10d3de863b9637ae914dd51e06c76c5.tar.gz frameworks_base-1bb0a456e10d3de863b9637ae914dd51e06c76c5.tar.bz2 |
Fix deadlock between ActivityManager and BackupManager under some race conditions.
Deadlock may happen when bind backup agent under some race condition.
If waiting for backup agent timeout, BackupManager will call to
ActivityManager's clearPendingBackup with mAgentConnectLock held.
During clearPendingBackup process, it will try to lock ActivityManager's
main lock. If app started up timeout at the same time, ActivityManager
will call to BackupManager's agentDisconnected with main lock held.
During agentDisconnected process, it will try to lock mAgentConnectLock.
Deadlock happened then.
In bindToAgentSynchronous process, move clearPendingBackup out of lock
area to fix this issue.
Change-Id: Ic1acfe1df8fd83d4acff5ce518d86cea4b2fe18b
Signed-off-by: lwan89 <liang.wang@intel.com>
Signed-off-by: Zhiquan Liu <zhiquan.liu@intel.com>
Diffstat (limited to 'services/backup/java')
-rw-r--r-- | services/backup/java/com/android/server/backup/BackupManagerService.java | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 13db985..b3bb9e6 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -2218,10 +2218,10 @@ public class BackupManagerService { // fire off a backup agent, blocking until it attaches or times out IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) { IBackupAgent agent = null; - synchronized(mAgentConnectLock) { - mConnecting = true; - mConnectedAgent = null; - try { + try { + synchronized(mAgentConnectLock) { + mConnecting = true; + mConnectedAgent = null; if (mActivityManager.bindBackupAgent(app, mode)) { Slog.d(TAG, "awaiting agent for " + app); @@ -2235,7 +2235,6 @@ public class BackupManagerService { } catch (InterruptedException e) { // just bail Slog.w(TAG, "Interrupted: " + e); - mActivityManager.clearPendingBackup(); return null; } } @@ -2243,14 +2242,22 @@ public class BackupManagerService { // if we timed out with no connect, abort and move on if (mConnecting == true) { Slog.w(TAG, "Timeout waiting for agent " + app); - mActivityManager.clearPendingBackup(); return null; } if (DEBUG) Slog.i(TAG, "got agent " + mConnectedAgent); agent = mConnectedAgent; } - } catch (RemoteException e) { + } + } catch (RemoteException e) { // can't happen - ActivityManager is local + } finally { + // failed to bind backup agent, clear pending backup + if (agent == null) { + try { + mActivityManager.clearPendingBackup(); + } catch (RemoteException e) { + // can't happen - ActivityManager is local + } } } return agent; |