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=9f89a0d8fa2a4f2ede8474513ac9f8ae5ce33de1;hb=e10760b08746837538ad4c2b4c37736aa34c7a47;hp=4ae530317908ce32118b867edaa6c85b52932d0d;hpb=0d9b90834ce56b292c00b1a39850ed842c3e4d42;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 4ae530317..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 @@ -12,56 +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; +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(); private final Object key; - private final ReadGraphImpl graph; + 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 graph, AsyncProcedure procedure, Object key) { + + 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, 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.graph = ReadGraphImpl.newAsync(graph); - this.graph.asyncBarrier.inc(); + this.queryGraph.asyncBarrier.inc(); + this.callerGraph = callerGraph; + this.needsToBlock = needsToBlock; + 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() { + queryGraph.asyncBarrier.waitBarrier(key, queryGraph); + } + + public void dec() { + + queryGraph.asyncBarrier.dec(); + } @SuppressWarnings("unchecked") public Result get() throws DatabaseException { - graph.asyncBarrier.waitBarrier(key, graph); + if(needsToBlock) + queryGraph.asyncBarrier.waitBarrier(key, queryGraph); if(exception != null) { if(exception instanceof DatabaseException) throw (DatabaseException)exception; @@ -85,5 +108,74 @@ public class BlockingAsyncProcedure implements AsyncProcedure { public String toString() { return "." + procedure; } + + @Override + public void run() { + + AsyncProcedure procedure__ = entry != null ? entry : procedure; + + 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()); + } + } 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); + } + + } + + 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(); + } + } }