From 3558e5f2277fe953c612b42576afe1fb8fae99c8 Mon Sep 17 00:00:00 2001 From: Marc Blank Date: Thu, 6 May 2010 11:10:16 -0700 Subject: [PATCH] Shut down Email process when sync is totally blocked * When sync threads get blocked by SSL/Socket code, we detect this and shutdown the ClientConnectionManager, hoping this will solve the problem. * Apparently, this doesn't always work. The result is that syncs are frozen until the device is rebooted (certainly) or until the Email process is stopped and restarted (hopefully) * This CL kills the Email process after an unsuccessful attempt to clear blocked threads using ClientConnectionManager.shutdown() Bug: 2615293 Change-Id: I8445b278817e508a855adeb88d6b2f969d28858b --- src/com/android/exchange/SyncManager.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java index 80594257b..1f5f9f498 100644 --- a/src/com/android/exchange/SyncManager.java +++ b/src/com/android/exchange/SyncManager.java @@ -76,6 +76,7 @@ import android.os.Debug; import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.PowerManager.WakeLock; @@ -174,6 +175,8 @@ public class SyncManager extends Service implements Runnable { // Service had a fatal error; can't run public static final int PING_STATUS_UNABLE = 3; + private static final int MAX_CLIENT_CONNECTION_MANAGER_SHUTDOWNS = 1; + // We synchronize on this for all actions affecting the service and error maps private static final Object sSyncLock = new Object(); // All threads can use this lock to wait for connectivity @@ -215,6 +218,8 @@ public class SyncManager extends Service implements Runnable { private static String sDeviceId = null; // ConnectionManager that all EAS threads can use private static ClientConnectionManager sClientConnectionManager = null; + // Count of ClientConnectionManager shutdowns + private static volatile int sClientConnectionManagerShutdownCount = 0; private boolean mStop = false; @@ -1162,6 +1167,12 @@ public class SyncManager extends Service implements Runnable { static public synchronized ClientConnectionManager getClientConnectionManager() { if (sClientConnectionManager == null) { + // After two tries, kill the process. Most likely, this will happen in the background + // The service will restart itself after about 5 seconds + if (sClientConnectionManagerShutdownCount > MAX_CLIENT_CONNECTION_MANAGER_SHUTDOWNS) { + alwaysLog("Shutting down process to unblock threads"); + Process.killProcess(Process.myPid()); + } // Create a registry for our three schemes; http and https will use built-in factories SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", @@ -1185,7 +1196,9 @@ public class SyncManager extends Service implements Runnable { static private synchronized void shutdownConnectionManager() { if (sClientConnectionManager != null) { + alwaysLog("Shutting down ClientConnectionManager"); sClientConnectionManager.shutdown(); + sClientConnectionManagerShutdownCount++; sClientConnectionManager = null; } } @@ -1465,7 +1478,7 @@ public class SyncManager extends Service implements Runnable { } // Shutdown the connection manager; this should close all of our // sockets and generate IOExceptions all around. - syncManager.shutdownConnectionManager(); + SyncManager.shutdownConnectionManager(); } } }}).start(); @@ -2295,6 +2308,10 @@ public class SyncManager extends Service implements Runnable { // TODO Handle this case } errorMap.remove(mailboxId); + // If we've had a successful sync, clear the shutdown count + synchronized (SyncManager.class) { + sClientConnectionManagerShutdownCount = 0; + } break; // I/O errors get retried at increasing intervals case AbstractSyncService.EXIT_IO_ERROR: