]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java
AsyncBarrier.dec runs into refcounting problem
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / BlockingAsyncProcedure.java
index 8f96bb9e6d3a51a48c7b98baa40f962fc83f5617..9f89a0d8fa2a4f2ede8474513ac9f8ae5ce33de1 100644 (file)
@@ -19,34 +19,31 @@ import org.simantics.db.impl.query.AsyncReadEntry;
 import org.simantics.db.impl.query.PendingTaskSupport;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.request.AsyncRead;
-public class BlockingAsyncProcedure<Result> implements AsyncProcedure<Result> {
+
+public class BlockingAsyncProcedure<Result> implements AsyncProcedure<Result>, Runnable {
 
     private static final Object NO_RESULT = new Object();
 
     private final Object key;
     private final ReadGraphImpl queryGraph;
     private final ReadGraphImpl callerGraph;
+    private final AsyncReadEntry<Result> entry;
     private final AsyncProcedure<Result> procedure;
     private PendingTaskSupport pendingTaskSupport;
     private final boolean needsToBlock;
     private Object result = NO_RESULT;
     private Throwable exception = null;
-
-    private ReadGraphImpl queryGraph() {
-        return queryGraph;
-    }
     
     public BlockingAsyncProcedure(ReadGraphImpl callerGraph, AsyncReadEntry<Result> entry, AsyncProcedure<Result> procedure, Object key, boolean needsToBlock) {
         
         // A new graph for evaluating the query with correct parent and asyncBarrier
-        queryGraph = callerGraph.withParent(entry, () -> {
-
-            dispatchProcedure(queryGraph(), callerGraph, entry, procedure, needsToBlock);
-            
-        }, needsToBlock);
-        
+        queryGraph = callerGraph.withParent(entry, this, needsToBlock);
         queryGraph.asyncBarrier.inc();
+        
+        // This makes sure that caller does not quit before dispatch
+        callerGraph.asyncBarrier.inc();
 
+        this.entry = entry;
         this.procedure = procedure;
         this.key = key;
         this.queryGraph.asyncBarrier.inc();
@@ -112,34 +109,39 @@ public class BlockingAsyncProcedure<Result> implements AsyncProcedure<Result> {
         return "." + procedure; 
     }
     
-    private void dispatchProcedure(ReadGraphImpl queryGraph, ReadGraphImpl parentGraph, AsyncReadEntry<Result> entry, AsyncProcedure<Result> procedure_, boolean needsToBlock) {
+    @Override
+    public void run() {
         
-        AsyncProcedure<Result> procedure = entry != null ? entry : procedure_;
+        AsyncProcedure<Result> procedure__ = entry != null ? entry : procedure;
 
-        ReadGraphImpl executeGraph = parentGraph.withParent(parentGraph.parent, null, needsToBlock);
+        ReadGraphImpl executeGraph = callerGraph.withParent(callerGraph.parent, null, needsToBlock);
         executeGraph.asyncBarrier.inc();
+        
+        // This counters the inc in the constructor 
+        callerGraph.asyncBarrier.dec();
+        
         try {
-            if(procedure != null) {
-                procedure.execute(executeGraph, get());
+            if(procedure__ != null) {
+                procedure__.execute(executeGraph, get());
             }
         } catch (DatabaseException e) {
-            if(procedure != null) procedure.exception(executeGraph, e);
+            if(procedure__ != null) procedure__.exception(executeGraph, e);
             exception = e;
         } catch (Throwable t) {
             DatabaseException dbe = new DatabaseException(t);
-            if(procedure != null) procedure.exception(executeGraph, dbe);
+            if(procedure__ != null) procedure__.exception(executeGraph, dbe);
             exception = dbe;
         } finally {
 
             if (entry != null) {
                 assert(entry.isReady());
                 // This does not throw
-                entry.performFromCache(executeGraph, procedure_);
+                entry.performFromCache(executeGraph, procedure);
             }
 
             executeGraph.asyncBarrier.dec();
             if(needsToBlock)
-                executeGraph.asyncBarrier.waitBarrier(procedure, executeGraph);
+                executeGraph.asyncBarrier.waitBarrier(procedure__, executeGraph);
         }
 
         if (BarrierTracing.BOOKKEEPING) {