X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.impl%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fimpl%2FBlockingAsyncProcedure.java;h=9f89a0d8fa2a4f2ede8474513ac9f8ae5ce33de1;hp=c491fb377464e366f5b34e8e8eac2e0e205840c5;hb=ae2e31aa5eb35410e5b2ce222d42421154f3fecc;hpb=90a52d58489b6c518b13dde238923125c8f63eec diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java index c491fb377..9f89a0d8f 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java @@ -18,38 +18,37 @@ import org.simantics.db.impl.graph.ReadGraphImpl; 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 implements AsyncProcedure { +public class BlockingAsyncProcedure implements AsyncProcedure, Runnable { private static final Object NO_RESULT = new Object(); - public final Object key; - public final ReadGraphImpl queryGraph; - public final ReadGraphImpl callerGraph; - public final AsyncProcedure procedure; - public PendingTaskSupport pendingTaskSupport; - public Object result = NO_RESULT; - public Throwable exception = null; - - private ReadGraphImpl queryGraph() { - return queryGraph; - } + private final Object key; + private final ReadGraphImpl queryGraph; + private final ReadGraphImpl callerGraph; + private final AsyncReadEntry entry; + private final AsyncProcedure procedure; + private PendingTaskSupport pendingTaskSupport; + private final boolean needsToBlock; + private Object result = NO_RESULT; + private Throwable exception = null; public BlockingAsyncProcedure(ReadGraphImpl callerGraph, AsyncReadEntry entry, AsyncProcedure 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); - - }); + // A new graph for evaluating the query with correct parent and asyncBarrier + 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(); this.callerGraph = callerGraph; + this.needsToBlock = needsToBlock; if (BarrierTracing.BOOKKEEPING) { BarrierTracing.registerBAP(this); } @@ -84,7 +83,8 @@ public class BlockingAsyncProcedure implements AsyncProcedure { @SuppressWarnings("unchecked") public Result get() throws DatabaseException { - queryGraph.asyncBarrier.waitBarrier(key, queryGraph); + if(needsToBlock) + queryGraph.asyncBarrier.waitBarrier(key, queryGraph); if(exception != null) { if(exception instanceof DatabaseException) throw (DatabaseException)exception; @@ -109,34 +109,39 @@ public class BlockingAsyncProcedure implements AsyncProcedure { return "." + procedure; } - private void dispatchProcedure(ReadGraphImpl queryGraph, ReadGraphImpl parentGraph, AsyncReadEntry entry, AsyncProcedure procedure_, boolean needsToBlock) { + @Override + public void run() { - AsyncProcedure procedure = entry != null ? entry : procedure_; + AsyncProcedure procedure__ = entry != null ? entry : procedure; - ReadGraphImpl executeGraph = parentGraph.withParent(parentGraph.parent); + 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) { @@ -144,5 +149,33 @@ public class BlockingAsyncProcedure implements AsyncProcedure { } } + + public void print() { + System.err.println("BlockingAsyncProcedure"); + System.err.println("-key: " + key); + System.err.println("-queryGraph: " + queryGraph); + System.err.println("-callerGraph: " + callerGraph); + System.err.println("-procedure: " + procedure); + System.err.println("-pendingTaskSupport: " + pendingTaskSupport); + System.err.println("-result: " + result); + System.err.println("-exception: " + exception); + } + + public Result performSync(AsyncRead request) throws DatabaseException { + try { + request.perform(queryGraph, this); + } finally { + dec(); + } + return get(); + } + + public void performAsync(AsyncRead request) throws DatabaseException { + try { + request.perform(queryGraph, this); + } finally { + dec(); + } + } }