X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.impl%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fimpl%2FBlockingAsyncProcedure.java;h=c491fb377464e366f5b34e8e8eac2e0e205840c5;hb=785f638bab44e70ec6103c3891daea95bcda9a07;hp=ad9f1643829fe506ac57125edaf2bc724a249d05;hpb=277b1c7fb3fdd8effb4bf2b447358d0e4ef0e302;p=simantics%2Fplatform.git 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 ad9f16438..c491fb377 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 @@ -12,60 +12,79 @@ package org.simantics.db.impl; import org.simantics.db.AsyncReadGraph; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; +import org.simantics.db.impl.graph.BarrierTracing; 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; public class BlockingAsyncProcedure implements AsyncProcedure { private static final Object NO_RESULT = new Object(); - private final Object key; - private final ReadGraphImpl graph; - private final AsyncProcedure procedure; + 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 Object result = NO_RESULT; - private Throwable exception = null; + private ReadGraphImpl queryGraph() { + return queryGraph; + } + + 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); + + }); + + queryGraph.asyncBarrier.inc(); - public BlockingAsyncProcedure(ReadGraphImpl graph, AsyncProcedure procedure, Object key) { this.procedure = procedure; this.key = key; - this.graph = graph; - this.graph.asyncBarrier.inc(); + this.queryGraph.asyncBarrier.inc(); + this.callerGraph = callerGraph; + if (BarrierTracing.BOOKKEEPING) { + BarrierTracing.registerBAP(this); + } } @Override - public void execute(AsyncReadGraph graph, Result result) { + public void execute(AsyncReadGraph graph_, Result result) { + this.result = result; - this.graph.asyncBarrier.dec(); - try { - if(procedure != null) procedure.execute(graph, result); - } catch (Throwable throwable) { - Logger.defaultLogError("AsyncProcedure.execute threw for " + procedure, throwable); - } + queryGraph.asyncBarrier.dec(); + } @Override - public void exception(AsyncReadGraph graph, Throwable t) { + public void exception(AsyncReadGraph graph_, Throwable t) { + this.exception = t; - try { - if(procedure != null) procedure.exception(graph, t); - } catch (Throwable throwable) { - Logger.defaultLogError("AsyncProcedure.exception threw for " + procedure, throwable); - } finally { - this.graph.asyncBarrier.dec(); - } + queryGraph.asyncBarrier.dec(); + } - + public void waitBarrier() { - graph.asyncBarrier.waitBarrier(key, graph); + queryGraph.asyncBarrier.waitBarrier(key, queryGraph); + } + + public void dec() { + + queryGraph.asyncBarrier.dec(); + } @SuppressWarnings("unchecked") public Result get() throws DatabaseException { - graph.asyncBarrier.waitBarrier(key, graph); + queryGraph.asyncBarrier.waitBarrier(key, queryGraph); if(exception != null) { if(exception instanceof DatabaseException) throw (DatabaseException)exception; @@ -76,10 +95,6 @@ public class BlockingAsyncProcedure implements AsyncProcedure { } - public boolean isDone() { - return graph.asyncBarrier.get() == 0; - } - @SuppressWarnings("unchecked") public Result getResult() { return (Result)result; @@ -93,5 +108,41 @@ public class BlockingAsyncProcedure implements AsyncProcedure { public String toString() { return "." + procedure; } + + private void dispatchProcedure(ReadGraphImpl queryGraph, ReadGraphImpl parentGraph, AsyncReadEntry entry, AsyncProcedure procedure_, boolean needsToBlock) { + + AsyncProcedure procedure = entry != null ? entry : procedure_; + + ReadGraphImpl executeGraph = parentGraph.withParent(parentGraph.parent); + executeGraph.asyncBarrier.inc(); + try { + if(procedure != null) { + procedure.execute(executeGraph, get()); + } + } catch (DatabaseException 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); + exception = dbe; + } finally { + + if (entry != null) { + assert(entry.isReady()); + // This does not throw + entry.performFromCache(executeGraph, procedure_); + } + + executeGraph.asyncBarrier.dec(); + if(needsToBlock) + executeGraph.asyncBarrier.waitBarrier(procedure, executeGraph); + } + + if (BarrierTracing.BOOKKEEPING) { + BarrierTracing.unregisterBAP(this); + } + + } }