Prevent wakelock from being held when sync services finish
* Make sure that ExchangeService#done is called when all threads
exit
* Make ExchangeService#done ensure that the calling thread is
still the active syncing thread for its mailbox before taking
action
* For MR0/MR1
Bug: 5256268
Change-Id: I64bc5f2539c524f3b8d633117ca1c548a373e449
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 7132fdd..a1f3a58 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -2477,10 +2477,9 @@
userLog("Uncaught exception in EasSyncService", e);
} finally {
int status;
-
+ ExchangeService.done(this);
if (!mStop) {
userLog("Sync finished");
- ExchangeService.done(this);
switch (mExitStatus) {
case EXIT_IO_ERROR:
status = EmailServiceStatus.CONNECTION_ERROR;
diff --git a/src/com/android/exchange/ExchangeService.java b/src/com/android/exchange/ExchangeService.java
index 153b7ed..d6d0a03 100644
--- a/src/com/android/exchange/ExchangeService.java
+++ b/src/com/android/exchange/ExchangeService.java
@@ -2075,6 +2075,12 @@
}
}
+ /**
+ * Release a mailbox from the service map and release its wake lock.
+ * NOTE: This method MUST be called while holding sSyncLock!
+ *
+ * @param mailboxId the id of the mailbox to be released
+ */
private void releaseMailbox(long mailboxId) {
mServiceMap.remove(mailboxId);
releaseWakeLock(mailboxId);
@@ -2521,6 +2527,13 @@
}
}
+ private boolean isRunningInServiceThread(long mailboxId) {
+ AbstractSyncService syncService = mServiceMap.get(mailboxId);
+ Thread thisThread = Thread.currentThread();
+ return syncService != null && syncService.mThread != null &&
+ thisThread == syncService.mThread;
+ }
+
/**
* Sent by services indicating that their thread is finished; action depends on the exitStatus
* of the service.
@@ -2532,9 +2545,15 @@
if (exchangeService == null) return;
synchronized(sSyncLock) {
long mailboxId = svc.mMailboxId;
+ // If we're no longer the syncing thread for the mailbox, just return
+ if (!exchangeService.isRunningInServiceThread(mailboxId)) {
+ return;
+ }
+ exchangeService.releaseMailbox(mailboxId);
+
ConcurrentHashMap<Long, SyncError> errorMap = exchangeService.mSyncErrorMap;
SyncError syncError = errorMap.get(mailboxId);
- exchangeService.releaseMailbox(mailboxId);
+
int exitStatus = svc.mExitStatus;
Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
if (m == null) return;