Fixes a race condition between the final worker thread and the main thread seeing that no threads are left.

Review by: spoon (desk)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@3365 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 db7eac3..9ca056c 100644
--- a/dev/core/src/com/google/gwt/dev/PermutationCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/PermutationCompiler.java
@@ -157,8 +157,11 @@
           tryToExitNonFinalThread(null);
 
           // As the last thread, I must inform the main thread we're all done.
-          results.add(FINISHED_RESULT);
-          exitFinalThread();
+          exitFinalThread(new Runnable() {
+            public void run() {
+              results.add(FINISHED_RESULT);
+            }
+          });
         }
 
         if (!hasEnoughMemory()) {
@@ -177,9 +180,12 @@
           if (definitelyFinalThread) {
             // OOM on the final thread, this is a truly unrecoverable failure.
             currentTask.logger.log(TreeLogger.ERROR, "Out of memory", e);
-            results.add(new FailedResult(currentTask.getPermutation(),
-                new UnableToCompleteException()));
-            exitFinalThread();
+            exitFinalThread(new Runnable() {
+              public void run() {
+                results.add(new FailedResult(currentTask.getPermutation(),
+                    new UnableToCompleteException()));
+              }
+            });
           }
 
           /*
@@ -203,8 +209,12 @@
       }
     }
 
-    private void exitFinalThread() {
-      assert threadCount.compareAndSet(1, 0);
+    private void exitFinalThread(Runnable actionOnExit) {
+      boolean isFinalThread = threadCount.compareAndSet(1, 0);
+      assert isFinalThread;
+      if (actionOnExit != null) {
+        actionOnExit.run();
+      }
       throw new ThreadDeath();
     }