]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java
Multiple readers in db client
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / QueryCache.java
index cc0ca919b584942a4d49a1a4c61b97b741e631f2..35ebdbc65ba4ce82e5e7e7dced301310c30f8b17 100644 (file)
@@ -625,7 +625,7 @@ public class QueryCache extends QueryCacheBase {
         }
     }
     
-    ReadEntry getOrCreateReadEntry(ReadGraphImpl graph, Read<?> r, boolean needsToBlock) throws DatabaseException {
+    private final ReadEntry getOrCreateReadEntry(ReadGraphImpl graph, Read<?> r, boolean needsToBlock) throws DatabaseException {
         ReadEntry existing = null;
         synchronized(readEntryMap) {
             existing = (ReadEntry)readEntryMap.get(r);
@@ -670,11 +670,13 @@ public class QueryCache extends QueryCacheBase {
         }
         ReadEntry entry = (ReadEntry)cache.getOrCreateReadEntry(graph, r, needsToBlock);
         if(entry == null) {
-          graph.processor.scheduleNow(new SessionTask(graph) {
+          graph.asyncBarrier.inc();  
+          graph.processor.scheduleNow(new SessionTask() {
             @Override
             public void run0(int thread) {
               try {
                 runnerReadEntry(graph, r, parent, listener, procedure, needsToBlock);
+                graph.asyncBarrier.dec();  
               } catch (DatabaseException e) {
                 Logger.defaultLogError(e);
               }
@@ -704,7 +706,7 @@ public class QueryCache extends QueryCacheBase {
         }
     }
     
-    AsyncReadEntry getOrCreateAsyncReadEntry(ReadGraphImpl graph, AsyncRead<?> r, boolean needsToBlock) throws DatabaseException {
+    AsyncReadEntry getOrCreateAsyncReadEntry(ReadGraphImpl graph, AsyncRead<?> r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure, boolean needsToBlock) throws DatabaseException {
         AsyncReadEntry existing = null;
         synchronized(asyncReadEntryMap) {
             existing = (AsyncReadEntry)asyncReadEntryMap.get(r);
@@ -721,11 +723,21 @@ public class QueryCache extends QueryCacheBase {
             }
         }
         if(existing.isPending()) {
-          if(needsToBlock)
-            waitPending(graph, existing);
-          else {
-            return null;
-          }
+            if(needsToBlock)
+                waitPending(graph, existing);
+            else {
+                existing.executeWhenResultIsAvailable(graph.processor, new SessionTask(graph) {
+                    @Override
+                    public void run0(int thread) {
+                        try {
+                            runnerAsyncReadEntry(graph, r, parent, listener, procedure, needsToBlock);
+                        } catch (DatabaseException e) {
+                            Logger.defaultLogError(e);
+                        }
+                    }
+                });
+                return null;
+            }
         }
         return existing;
     }
@@ -747,19 +759,10 @@ public class QueryCache extends QueryCacheBase {
             }
             return AsyncReadEntry.computeForEach(graph, r, null, procedure, needsToBlock);
         }
-        AsyncReadEntry entry = (AsyncReadEntry)cache.getOrCreateAsyncReadEntry(graph, r, needsToBlock);
+        AsyncReadEntry entry = (AsyncReadEntry)cache.getOrCreateAsyncReadEntry(graph, r, parent, listener, procedure, needsToBlock);
         if(entry == null) {
-          graph.processor.scheduleNow(new SessionTask(graph) {
-            @Override
-            public void run0(int thread) {
-              try {
-                runnerAsyncReadEntry(graph, r, parent, listener, procedure, needsToBlock);
-              } catch (DatabaseException e) {
-                Logger.defaultLogError(e);
-              }
-            }
-          });
-          return null;
+            // Entry was pending and this request has been queued  
+            return null;
         }
         AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureAsyncReadEntry;
         if(entry.isReady()) {