]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java
Still working for multiple readers
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / procedure / BlockingAsyncProcedure.java
diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java
new file mode 100644 (file)
index 0000000..d239c87
--- /dev/null
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.common.procedure;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.AsyncProcedure;
+
+public class BlockingAsyncProcedure<Result> implements AsyncProcedure<Result> {
+
+       final private Object key;
+    private Result result = null;
+    private Throwable exception = null;
+    final private AsyncProcedure<Result> procedure;
+    final private Semaphore semaphore = new Semaphore(0);
+//    final private AtomicBoolean latch;
+    
+    public BlockingAsyncProcedure(AsyncProcedure<Result> procedure, Object key) {
+//     assert(procedure != null);
+       this.key = key;
+        this.procedure = procedure;
+        if(key == null)
+               System.err.println("asd");
+        //System.err.println("BlockingAsyncProcedure " + key);
+//        latch = new AtomicBoolean(false);
+    }
+    
+    @Override
+    public void execute(AsyncReadGraph graph, Result result) {
+        this.result = result;
+        semaphore.release();
+//        if(latch.compareAndSet(false, true)) {
+               try {
+                       if(procedure != null) procedure.execute(graph, result);
+               } catch (Throwable throwable) {
+               Logger.defaultLogError("AsyncProcedure.execute threw for " + procedure, throwable);
+               }
+//             } finally {
+////                   System.err.println("ResultCallWrappedSingleQueryProcedure4 dec " + key);
+//             }
+//        } else {
+//             Logger.defaultLogError("Procedure was called many times (this time is execute)");
+//        }
+    }
+
+    @Override
+    public void exception(AsyncReadGraph graph, Throwable t) {
+        this.exception = t;
+        semaphore.release();
+//        if(latch.compareAndSet(false, true)) {
+               try {
+                       if(procedure != null) procedure.exception(graph, t);
+               } catch (Throwable throwable) {
+               Logger.defaultLogError("AsyncProcedure.exception threw for " + procedure, throwable);
+               } finally {
+               }
+//        } else {
+//             Logger.defaultLogError("Procedure was called many times (this time is exception)");
+//        }
+        
+    }
+    
+    public Result get() throws DatabaseException {
+       
+       try {
+                       boolean success = semaphore.tryAcquire(10, TimeUnit.SECONDS);
+                       if(!success) throw new DatabaseException("Timeout while waiting for async request to complete: " + key);
+               } catch (InterruptedException e) {
+                       throw new DatabaseException(e);
+               }
+       
+       if(exception != null) {
+               if(exception instanceof DatabaseException) throw (DatabaseException)exception;
+               throw new DatabaseException(exception);
+       } else {
+               return result;
+       }
+       
+    }
+    
+    public Result getResult() {
+        return result;
+    }
+    
+    public Throwable getException() {
+        return exception;
+    }
+       
+    @Override
+    public String toString() {
+        return "." + procedure; 
+    }
+    
+}