Uncommon Acorn deadlock fix 32/732/2
authorjsimomaa <jani.simomaa@gmail.com>
Thu, 20 Jul 2017 06:53:12 +0000 (09:53 +0300)
committerJani Simomaa <jani.simomaa@semantum.fi>
Thu, 20 Jul 2017 12:56:10 +0000 (15:56 +0300)
refs #7373

Change-Id: Ica31908fca0b70da87bbcf75deb2476bdf305cde

bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java

index 450ad0618fe84445d68a39427a9095f464d8c81a..c69c7bea6fe7957bf3c408256a6d9f5cbfed16e4 100644 (file)
@@ -20,9 +20,13 @@ import org.simantics.acorn.lru.ClusterStreamChunk;
 import org.simantics.acorn.lru.ClusterUpdateOperation;
 import org.simantics.db.service.ClusterUID;
 import org.simantics.utils.logging.TimeLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class MainProgram implements Runnable, Closeable {
 
+       private static final Logger LOGGER = LoggerFactory.getLogger(MainProgram.class);
+       
        private static final int CLUSTER_THREADS = 4;
        private static final int CHUNK_CACHE_SIZE = 100;
 
@@ -260,14 +264,32 @@ public class MainProgram implements Runnable, Closeable {
 
        public Exception runIdle(MainProgramRunnable runnable) {
                try {
-                       mutex.acquire();
-                       runnable.run();
-                       return null;
-               } catch (Exception e) {
-                       return e;
+                       long startTime = System.currentTimeMillis();
+                       while (true) {
+                               boolean hasMutex = false;
+                               try {
+                                       synchronized (MainProgram.this) {
+                                               if (hasMutex = mutex.tryAcquire()) {
+                                                       if (operations.isEmpty()) {
+                                                               runnable.run();
+                                                               return null;
+                                                       }
+                                               }
+                                       }
+                                       long endTime = System.currentTimeMillis(); 
+                                       if ((endTime - startTime) > 100) {
+                                               startTime = endTime; 
+                                               LOGGER.info("MainProgram.runIdle() retry mutex acquire!");
+                                       }
+                               } catch (Exception e) {
+                                       return e;
+                               } finally {
+                                       if (hasMutex)
+                                               mutex.release();
+                               }
+                       }
                } finally {
                        runnable.done();
-                       mutex.release();
                }
        }
        
@@ -297,7 +319,7 @@ public class MainProgram implements Runnable, Closeable {
 
                ClusterStreamChunk last = operations.isEmpty() ? null : operations.getLast();
         if (!alive) {
-            System.err.println("Trying to commit operation after MainProgram is closed! Operation is " + last);
+            LOGGER.error("Trying to commit operation after MainProgram is closed! Operation is " + last);
 //          return;
         }
                if(last != null) last.commit();
@@ -306,7 +328,7 @@ public class MainProgram implements Runnable, Closeable {
 
        public synchronized void schedule(ClusterUpdateOperation operation) throws IllegalAcornStateException {
            if (!alive) {
-               System.err.println("Trying to schedule operation after MainProgram is closed! Operation is " + operation);
+               LOGGER.error("Trying to schedule operation after MainProgram is closed! Operation is " + operation);
 //             return;
            }
                clusters.streamLRU.acquireMutex();