Patch fixes the deadlock issue with the HtmlUnit plugin in the UiSuite.

Patch by: amitmanjhi
Review by: kprobst (TBR)



git-svn-id: https://google-web-toolkit.googlecode.com/svn/branches/farewellSwt@6258 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelClient.java b/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelClient.java
index c268194..776dfc6 100644
--- a/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelClient.java
+++ b/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelClient.java
@@ -63,6 +63,7 @@
   private final String url;
   private final String versionString;
   private boolean connected = false;
+  boolean shouldDisconnect = false;
 
   public BrowserChannelClient(String addressParts[], String url,
       String sessionKey, String moduleName, String versionString,
@@ -114,6 +115,9 @@
       new LoadModuleMessage(this, url, tabKey, sessionKey, moduleName,
           htmlUnitSessionHandler.getUserAgent()).send();
       returnMessage = reactToMessages(htmlUnitSessionHandler, true);
+      if (shouldDisconnect) {
+        disconnectFromHost();
+      }
     }
     logger.log(TreeLogger.DEBUG, "loaded module, returnValue: "
         + returnMessage.getReturnValue() + ", isException: "
@@ -124,7 +128,11 @@
   public ReturnMessage reactToMessagesWhileWaitingForReturn(
       HtmlUnitSessionHandler handler) throws IOException,
       BrowserChannelException {
-    return reactToMessages(handler, true);
+    ReturnMessage returnMessage = reactToMessages(handler, true);
+    if (shouldDisconnect) {
+      disconnectFromHost();
+    }
+    return returnMessage;
   }
 
   /*
@@ -174,7 +182,7 @@
                 invokeMessage.getArgs());
             htmlUnitSessionHandler.sendFreeValues(this);
             new ReturnMessage(this, returnValue.isException(),
-                returnValue.getReturnValue()).send();
+                returnValue.getReturnValue()).send();           
             break;
           case INVOKE_SPECIAL:
             InvokeSpecialMessage invokeSpecialMessage = InvokeSpecialMessage.receive(this);
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java b/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
index ec5fe27..64c85f0 100644
--- a/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
+++ b/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
@@ -83,6 +83,7 @@
   }
 
   private static final Value EMPTY_VALUES[] = new Value[0];
+  private static final String REPLACE_METHOD_SIGNATURE = "@com.google.gwt.user.client.Window$Location::replace(Ljava/lang/String;)";
   private static final int TO_STRING_DISPATCH_ID = 0;
 
   Map<Integer, JavaObject> javaObjectCache;
@@ -201,8 +202,20 @@
     }
     Object result = null;
     try {
+      if (args.length == 1
+          && methodName.indexOf(REPLACE_METHOD_SIGNATURE) != -1) {
+        // getUrl() is not visible
+        String currentUrl = window.jsxGet_location().toString();
+        currentUrl = getUrlBeforeHash(currentUrl);
+        String newUrl = getUrlBeforeHash((String) args[0].getValue());
+        if (!newUrl.equals(currentUrl)) {
+          // TODO: removeAllJobs for all windows?
+          window.getWebWindow().getTopWindow().getJobManager().removeAllJobs();
+          ((BrowserChannelClient) channel).shouldDisconnect = true;
+        }
+      }
       result = jsEngine.callFunction(htmlPage, jsFunction, jsContext, window,
-          jsThis, jsArgs);
+          jsThis, jsArgs);     
     } catch (JavaScriptException ex) {
       logger.log(TreeLogger.INFO, "INVOKE: JavaScriptException " + ex
           + ", message: " + ex.getMessage() + " when invoking " + methodName);
@@ -346,4 +359,12 @@
     return null;
   }
 
+  private String getUrlBeforeHash(String currentUrl) {
+    int hashIndex = -1;
+    if ((hashIndex = currentUrl.indexOf("#")) != -1) {
+      currentUrl = currentUrl.substring(0, hashIndex);
+    }
+    return currentUrl;
+  }
+
 }