summaryrefslogtreecommitdiffstats
path: root/services/backup/java
diff options
context:
space:
mode:
authorlwan89x <liangx.wang@intel.com>2014-09-24 18:27:49 +0800
committerSteve Kondik <steve@cyngn.com>2015-11-07 05:40:43 -0800
commit1bb0a456e10d3de863b9637ae914dd51e06c76c5 (patch)
treec31b2c5d618352c971fd41a38eba0ccad268d1cf /services/backup/java
parent3d4374ef467d0f610b9bf1e9cacf0ca44f4d09ef (diff)
downloadframeworks_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.java21
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;