]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.interop.scl/src/org/simantics/interop/scl/Threads.java
SCL threads support
[simantics/interop.git] / org.simantics.interop.scl / src / org / simantics / interop / scl / Threads.java
diff --git a/org.simantics.interop.scl/src/org/simantics/interop/scl/Threads.java b/org.simantics.interop.scl/src/org/simantics/interop/scl/Threads.java
new file mode 100644 (file)
index 0000000..f077492
--- /dev/null
@@ -0,0 +1,93 @@
+package org.simantics.interop.scl;
+
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function;
+import org.simantics.scl.runtime.tuple.Tuple0;
+
+public class Threads {
+       
+       private static final AtomicInteger threadCount = new AtomicInteger(0);
+       
+    private static final ThreadFactory threadFactory = r -> {
+               Thread t = new Thread(r, "scl-interop-thread-" + threadCount.incrementAndGet());
+               t.setDaemon(true);
+               return t;
+           };
+
+
+       private static final ScheduledThreadPoolExecutor scheduledExecutor;
+          
+       static {
+               scheduledExecutor = new ScheduledThreadPoolExecutor(2, threadFactory);
+               scheduledExecutor.setMaximumPoolSize(2);
+       }
+       
+       public static void setMaximumPoolSize(int size) {
+               if (size < 2)
+                       return;
+               scheduledExecutor.setMaximumPoolSize(size);
+       }
+       
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public static SCLThread runAsync(Function f) {
+        SCLContext context = SCLContext.createDerivedContext();
+        SCLThread t = new SCLThread(context,f);
+        scheduledExecutor.submit(t);
+        return t;
+    }
+       
+       public static class SCLThread implements Runnable {
+               SCLContext context;
+               Function f;
+               boolean running = false;
+               boolean completed = false;
+               Object returnValue = null;
+               Throwable error;
+               
+               public SCLThread(SCLContext context, Function f) {
+                       this.context = context;
+                       this.f = f;
+               }
+               
+               @Override
+               public void run() {
+                       SCLContext.push(context);
+                       running = true;
+                       try {
+                               returnValue = f.apply(Tuple0.INSTANCE);
+                       } catch (Throwable t) {
+                               error = t;
+                       } finally {
+                SCLContext.pop();
+            }
+                       running = false;
+                       completed = true;
+               }
+               
+               public boolean isRunning() {
+                       return running;
+               }
+               
+               public boolean isCompleted() {
+                       return completed;
+               }
+               
+               public boolean hasErrors() {
+                       return error != null;
+               }
+               
+               public Object getReturnValue() {
+                       return returnValue;
+               }
+               
+               public Throwable getError() {
+                       return error;
+               }
+               
+       }
+
+}