Removes the threading from SuperDevListener.

This is causing multi-threading issues with compiler
as it does have un-syncrhonized static state.

I couldn't observe any performance difference above the noise level
while testing this with Hello sample app and GWT source.
In single thread I was getting consistently 19 seconds while I was
getting 18.5 to 19+ seconds with the extra thread. Besides this is
the DevMode launch time so even a few seconds shouldn't matter
much.

Bug: issue 9055
Change-Id: I5384904df9d108ae736b6ce0455b90dfaa6e0c63
diff --git a/dev/core/src/com/google/gwt/dev/DevMode.java b/dev/core/src/com/google/gwt/dev/DevMode.java
index 760dec4..6d0499c 100644
--- a/dev/core/src/com/google/gwt/dev/DevMode.java
+++ b/dev/core/src/com/google/gwt/dev/DevMode.java
@@ -513,28 +513,13 @@
                 + module.getCanonicalName() + "'");
         link(loadLogger, module);
       }
-
     } catch (UnableToCompleteException e) {
       // Already logged.
       return false;
     } finally {
       slowStartupEvent.end();
     }
-
-    // When in GWTTestCase and not using Dev Mode, there is no listener.
-    if (listener == null) {
-      return true;
-    }
-
-    // When this methods exits, the buttons will be enabled in the Swing UI.
-    // We shouldn't do that until the code server is ready, or the user might
-    // see a blank page.
-    try {
-      listener.waitUntilReady(getTopLogger());
-      return true;
-    } catch (UnableToCompleteException e) {
-      return false; // already logged
-    }
+    return true;
   }
 
   @Override
diff --git a/dev/core/src/com/google/gwt/dev/shell/BrowserListener.java b/dev/core/src/com/google/gwt/dev/shell/BrowserListener.java
index 3081041..e727c5c 100644
--- a/dev/core/src/com/google/gwt/dev/shell/BrowserListener.java
+++ b/dev/core/src/com/google/gwt/dev/shell/BrowserListener.java
@@ -210,9 +210,4 @@
       listenThread.start();
     }
   }
-
-  @Override
-  public void waitUntilReady(TreeLogger logger) throws UnableToCompleteException {
-    // already ready when constructor returns.
-  }
 }
diff --git a/dev/core/src/com/google/gwt/dev/shell/CodeServerListener.java b/dev/core/src/com/google/gwt/dev/shell/CodeServerListener.java
index a9914ba..6432fdc 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CodeServerListener.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CodeServerListener.java
@@ -13,7 +13,6 @@
  */
 package com.google.gwt.dev.shell;
 
-import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.linker.ArtifactSet;
 import com.google.gwt.core.ext.linker.impl.StandardLinkerContext;
@@ -32,17 +31,11 @@
   int getSocketPort();
 
   /**
-   * Starts the code server. (It won't be ready until the {@link #waitUntilReady returns.)
+   * Starts the code server.
    */
   void start();
 
   /**
-   * Blocks until the code server ready to handle requests.
-   * @throws UnableToCompleteException if unable to start.
-   */
-  void waitUntilReady(TreeLogger logger) throws UnableToCompleteException;
-
-  /**
    * Returns the URL to use in the browser for using this codeserver.
    */
   URL makeStartupUrl(String url) throws UnableToCompleteException;
diff --git a/dev/core/src/com/google/gwt/dev/shell/SuperDevListener.java b/dev/core/src/com/google/gwt/dev/shell/SuperDevListener.java
index d266e2a..03fe2d4 100644
--- a/dev/core/src/com/google/gwt/dev/shell/SuperDevListener.java
+++ b/dev/core/src/com/google/gwt/dev/shell/SuperDevListener.java
@@ -24,9 +24,9 @@
 import com.google.gwt.dev.cfg.ModuleDef;
 import com.google.gwt.dev.util.arg.OptionJsInteropMode;
 import com.google.gwt.dev.util.arg.OptionMethodNameDisplayMode;
+import com.google.gwt.thirdparty.guava.common.base.Stopwatch;
 import com.google.gwt.thirdparty.guava.common.collect.ListMultimap;
 import com.google.gwt.thirdparty.guava.common.collect.Lists;
-import com.google.gwt.thirdparty.guava.common.util.concurrent.SettableFuture;
 
 import java.io.File;
 import java.io.IOException;
@@ -36,17 +36,15 @@
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.ExecutionException;
 
 /**
  * Starts a superdev-mode codeserver.
  */
 public class SuperDevListener implements CodeServerListener {
 
-  private final Thread listenThread;
   private final TreeLogger logger;
   private final int codeServerPort;
-  private final SettableFuture<Void> codeServerReady = SettableFuture.create();
+  private List<String> codeServerArgs;
 
   /**
    * Listens for new connections from browsers.
@@ -58,44 +56,7 @@
     // This directory must exist when the Code Server starts.
     ensureModuleBaseDir(options);
 
-    List<String> args = makeCodeServerArgs(options, codeServerPort);
-
-    final String[] codeServerArgs = args.toArray(new String[0]);
-
-    logger.log(Type.INFO, "Runing CodeServer with parameters: " + args);
-
-    // Using reflection so as we don't create a circular dependency between
-    // dev.jar && codeserver.jar
-    final Method mainMethod;
-    try {
-      Class<?> clazz = Class.forName("com.google.gwt.dev.codeserver.CodeServer");
-      mainMethod = clazz.getMethod("main", String[].class);
-    } catch (ClassNotFoundException e) {
-      logger.log(TreeLogger.ERROR, "Unable to find main() method for Super Dev Mode "
-          + "code server. Hint: verify that gwt-codeserver.jar is in your classpath.");
-      throw new RuntimeException(e);
-    } catch (NoSuchMethodException e) {
-      logger.log(TreeLogger.ERROR, "Unable to run superdev codeServer.", e);
-      throw new RuntimeException(e);
-    }
-
-    listenThread = new Thread() {
-      public void run() {
-        try {
-          long startTime = System.currentTimeMillis();
-          mainMethod.invoke(null, new Object[] {codeServerArgs});
-          long elapsedTime = System.currentTimeMillis() - startTime;
-          logger.log(Type.INFO, "Code server started in " + elapsedTime + " ms");
-          // The main method returns when the code server has finished launching.
-          codeServerReady.set(null);
-        } catch (Exception e) {
-          logger.log(TreeLogger.ERROR, "Unable to run superdev codeServer.", e);
-          codeServerReady.setException(e);
-        }
-      }
-    };
-    listenThread.setName("SuperDevMode code server listener");
-    listenThread.setDaemon(true);
+    codeServerArgs = makeCodeServerArgs(options, codeServerPort);
   }
 
   @Override
@@ -125,24 +86,31 @@
 
   @Override
   public void start() {
-    listenThread.start();
+    try {
+      Stopwatch watch = Stopwatch.createStarted();
+      logger.log(Type.INFO, "Runing CodeServer with parameters: " + codeServerArgs);
+      runCodeServer(codeServerArgs.toArray(new String[0]));
+      logger.log(Type.INFO, "Code server started in " + watch + " ms");
+    } catch (Exception e) {
+      logger.log(Type.INFO, "Unable to start Code server");
+      throw new RuntimeException(e);
+    }
   }
 
-  @Override
-  public void waitUntilReady(TreeLogger logger) throws UnableToCompleteException {
-    long startTime = System.currentTimeMillis();
+  private void runCodeServer(String[] mainArgs) throws Exception {
+    // Using reflection so as we don't create a circular dependency between
+    // dev.jar && codeserver.jar
+    Method mainMethod;
     try {
-      codeServerReady.get();
-    } catch (InterruptedException e) {
-      logger.log(Type.ERROR, "thread interrupted while waiting for code server");
-      throw new UnableToCompleteException();
-    } catch (ExecutionException e) {
-      logger.log(Type.ERROR, "unable to launch code server", e);
-      throw new UnableToCompleteException();
-    } finally {
-      long elapsedTime = System.currentTimeMillis() - startTime;
-      logger.log(Type.INFO, "waited " + elapsedTime + " ms for code server to finish");
+      Class<?> clazz = Class.forName("com.google.gwt.dev.codeserver.CodeServer");
+      mainMethod = clazz.getMethod("main", String[].class);
+    } catch (ClassNotFoundException e) {
+      logger.log(TreeLogger.ERROR, "Unable to find main() method for Super Dev Mode "
+          + "code server. Hint: verify that gwt-codeserver.jar is in your classpath.");
+      throw e;
     }
+
+    mainMethod.invoke(null, new Object[] {mainArgs});
   }
 
   private static int chooseCodeServerPort(TreeLogger logger, HostedModeOptions options) {