JAL-4312 defend against ConcurrentModificationException
[jalview.git] / src / jalview / workers / AlignCalcManager.java
index addb372..508a069 100644 (file)
@@ -25,6 +25,7 @@ import jalview.api.AlignCalcWorkerI;
 import jalview.datamodel.AlignmentAnnotation;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Hashtable;
@@ -68,12 +69,12 @@ public class AlignCalcManager implements AlignCalcManagerI
   {
     restartable = Collections
             .synchronizedList(new ArrayList<AlignCalcWorkerI>());
-    blackList = Collections
-            .synchronizedList(new ArrayList<Class<? extends AlignCalcWorkerI>>());
+    blackList = Collections.synchronizedList(
+            new ArrayList<Class<? extends AlignCalcWorkerI>>());
     inProgress = Collections
             .synchronizedList(new ArrayList<AlignCalcWorkerI>());
-    updating = Collections
-            .synchronizedMap(new Hashtable<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>>());
+    updating = Collections.synchronizedMap(
+            new Hashtable<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>>());
     canUpdate = new HashSet<AlignCalcWorkerI>();
   }
 
@@ -85,10 +86,8 @@ public class AlignCalcManager implements AlignCalcManagerI
       List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
       if (upd == null)
       {
-        updating.put(
-                worker.getClass(),
-                upd = Collections
-                        .synchronizedList(new ArrayList<AlignCalcWorkerI>()));
+        updating.put(worker.getClass(), upd = Collections
+                .synchronizedList(new ArrayList<AlignCalcWorkerI>()));
       }
       synchronized (upd)
       {
@@ -146,7 +145,7 @@ public class AlignCalcManager implements AlignCalcManagerI
   {
     synchronized (inProgress)
     {
-      // System.err.println("Worker " + worker + " marked as complete.");
+      // jalview.bin.Console.errPrintln("Worker " + worker + " marked as complete.");
       inProgress.remove(worker);
       List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
       if (upd != null)
@@ -193,7 +192,7 @@ public class AlignCalcManager implements AlignCalcManagerI
   public boolean isWorking(AlignCalcWorkerI worker)
   {
     synchronized (inProgress)
-    {// System.err.println("isWorking : worker "+(worker!=null ?
+    {// jalview.bin.Console.errPrintln("isWorking : worker "+(worker!=null ?
      // worker.getClass():"null")+ " "+hashCode());
       return worker != null && inProgress.contains(worker);
     }
@@ -202,11 +201,29 @@ public class AlignCalcManager implements AlignCalcManagerI
   @Override
   public boolean isWorking()
   {
+    boolean working=false;
     synchronized (inProgress)
     {
-      // System.err.println("isWorking "+hashCode());
-      return inProgress.size() > 0;
+      // jalview.bin.Console.errPrintln("isWorking "+hashCode());
+      working |= inProgress.size() > 0;
     }
+    synchronized (updating)
+    {
+      Collection<List<AlignCalcWorkerI>> workersLists = updating.values();
+      synchronized (workersLists)
+      {
+        for (List<AlignCalcWorkerI> workers : workersLists)
+        {
+          if (workers!=null)
+          {
+            synchronized (workers) {
+              working |= workers.size() > 0;
+            }
+          }
+        }
+      }
+    }
+    return working;
   }
 
   @Override
@@ -235,7 +252,8 @@ public class AlignCalcManager implements AlignCalcManagerI
   }
 
   @Override
-  public boolean workingInvolvedWith(AlignmentAnnotation alignmentAnnotation)
+  public boolean workingInvolvedWith(
+          AlignmentAnnotation alignmentAnnotation)
   {
     synchronized (inProgress)
     {
@@ -287,14 +305,16 @@ public class AlignCalcManager implements AlignCalcManagerI
           Class<? extends AlignCalcWorkerI> workerClass)
   {
     List<AlignCalcWorkerI> workingClass = new ArrayList<AlignCalcWorkerI>();
+    AlignCalcWorkerI[] workers;
     synchronized (canUpdate)
     {
-      for (AlignCalcWorkerI worker : canUpdate)
+      workers = canUpdate.toArray(new AlignCalcWorkerI[0]);
+    }
+    for (AlignCalcWorkerI worker : workers)
+    {
+      if (workerClass.equals(worker.getClass()))
       {
-        if (workerClass.equals(worker.getClass()))
-        {
-          workingClass.add(worker);
-        }
+        workingClass.add(worker);
       }
     }
     return (workingClass.size() == 0) ? null : workingClass;
@@ -349,7 +369,7 @@ public class AlignCalcManager implements AlignCalcManagerI
      * {
      * 
      * if (isPending(worker)) { worker.abortAndDestroy(); startWorker(worker); }
-     * else { System.err.println("Pending exists for " + workerClass); } }
+     * else { jalview.bin.Console.errPrintln("Pending exists for " + workerClass); } }
      */
   }