Catch our ThreadDeath to avoid tripping up debuggers.

Suggested by: knorton

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@3447 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/PermutationCompiler.java b/dev/core/src/com/google/gwt/dev/PermutationCompiler.java
index 9ca056c..6069588 100644
--- a/dev/core/src/com/google/gwt/dev/PermutationCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/PermutationCompiler.java
@@ -150,62 +150,69 @@
     };
 
     public void run() {
-      while (true) {
-        currentTask = tasks.poll();
-        if (currentTask == null) {
-          // Nothing left to do.
-          tryToExitNonFinalThread(null);
+      try {
+        while (true) {
+          doTask();
+        }
+      } catch (ThreadDeath expected) {
+      }
+    }
 
-          // As the last thread, I must inform the main thread we're all done.
+    protected void doTask() throws ThreadDeath {
+      currentTask = tasks.poll();
+      if (currentTask == null) {
+        // Nothing left to do.
+        tryToExitNonFinalThread(null);
+
+        // As the last thread, I must inform the main thread we're all done.
+        exitFinalThread(new Runnable() {
+          public void run() {
+            results.add(FINISHED_RESULT);
+          }
+        });
+      }
+
+      if (!hasEnoughMemory()) {
+        /*
+         * Not enough memory to run, but if there are multiple threads, we can
+         * try again with fewer threads.
+         */
+        tryToExitNonFinalThread(outOfMemoryRetryAction);
+      }
+
+      boolean definitelyFinalThread = (threadCount.get() == 1);
+      try {
+        String result = currentTask.call();
+        results.add(new SuccessResult(currentTask.getPermutation(), result));
+      } catch (OutOfMemoryError e) {
+        if (definitelyFinalThread) {
+          // OOM on the final thread, this is a truly unrecoverable failure.
+          currentTask.logger.log(TreeLogger.ERROR, "Out of memory", e);
           exitFinalThread(new Runnable() {
             public void run() {
-              results.add(FINISHED_RESULT);
+              results.add(new FailedResult(currentTask.getPermutation(),
+                  new UnableToCompleteException()));
             }
           });
         }
 
-        if (!hasEnoughMemory()) {
-          /*
-           * Not enough memory to run, but if there are multiple threads, we can
-           * try again with fewer threads.
-           */
-          tryToExitNonFinalThread(outOfMemoryRetryAction);
-        }
+        /*
+         * Try the task again with fewer threads, it may not OOM this time.
+         */
+        tryToExitNonFinalThread(outOfMemoryRetryAction);
 
-        boolean definitelyFinalThread = (threadCount.get() == 1);
-        try {
-          String result = currentTask.call();
-          results.add(new SuccessResult(currentTask.getPermutation(), result));
-        } catch (OutOfMemoryError e) {
-          if (definitelyFinalThread) {
-            // OOM on the final thread, this is a truly unrecoverable failure.
-            currentTask.logger.log(TreeLogger.ERROR, "Out of memory", e);
-            exitFinalThread(new Runnable() {
-              public void run() {
-                results.add(new FailedResult(currentTask.getPermutation(),
-                    new UnableToCompleteException()));
-              }
-            });
-          }
-
-          /*
-           * Try the task again with fewer threads, it may not OOM this time.
-           */
-          tryToExitNonFinalThread(outOfMemoryRetryAction);
-
-          /*
-           * Okay, so we actually are the final thread. However, we weren't the
-           * final thread at the beginning of the compilation, so it's possible
-           * that a retry may now succeed with only one active thread. Let's
-           * optimistically retry one last time, and if this doesn't work, it's
-           * a hard failure.
-           */
-          outOfMemoryRetryAction.run();
-        } catch (Throwable e) {
-          // Unexpected error compiling, this is unrecoverable.
-          results.add(new FailedResult(currentTask.getPermutation(), e));
-          throw new ThreadDeath();
-        }
+        /*
+         * Okay, so we actually are the final thread. However, we weren't the
+         * final thread at the beginning of the compilation, so it's possible
+         * that a retry may now succeed with only one active thread. Let's
+         * optimistically retry one last time, and if this doesn't work, it's a
+         * hard failure.
+         */
+        outOfMemoryRetryAction.run();
+      } catch (Throwable e) {
+        // Unexpected error compiling, this is unrecoverable.
+        results.add(new FailedResult(currentTask.getPermutation(), e));
+        throw new ThreadDeath();
       }
     }