]> gerrit.simantics Code Review - simantics/interop.git/commitdiff
SCL threads support 56/3856/1
authorMarko Luukkainen <marko.luukkainen@semantum.fi>
Fri, 7 Feb 2020 10:15:49 +0000 (12:15 +0200)
committerMarko Luukkainen <marko.luukkainen@semantum.fi>
Fri, 7 Feb 2020 10:15:49 +0000 (12:15 +0200)
gitlab #22

Change-Id: I18e2cf1b2f7d45624362bd0712964e6ed5b08a94

org.simantics.interop.scl/META-INF/MANIFEST.MF
org.simantics.interop.scl/scl/Interop/Threads.scl [new file with mode: 0644]
org.simantics.interop.scl/src/org/simantics/interop/scl/Threads.java [new file with mode: 0644]

index 008487ba28cf70b877bc971ec72a60b6d5e86db5..93c3c689855d495649b21873f84c2d0ef90b6c6e 100644 (file)
@@ -11,4 +11,5 @@ Require-Bundle: org.simantics.scl.data;bundle-version="1.0.0",
  org.simantics.scl.osgi;bundle-version="1.0.4",
  org.simantics.scl.reflection;bundle-version="1.0.0",
  org.simantics.scl.runtime;bundle-version="0.4.0",
- org.simantics.utils.datastructures;bundle-version="1.1.0"
+ org.simantics.utils.datastructures;bundle-version="1.1.0",
+ org.simantics.utils.thread;bundle-version="1.1.0"
diff --git a/org.simantics.interop.scl/scl/Interop/Threads.scl b/org.simantics.interop.scl/scl/Interop/Threads.scl
new file mode 100644 (file)
index 0000000..84cb606
--- /dev/null
@@ -0,0 +1,15 @@
+importJava "org.simantics.interop.scl.Threads" where
+  
+  runAsync :: (<Proc>()) -> <Proc> SCLThread
+  
+  setMaximumPoolSize :: Integer -> <Proc> ()
+
+importJava "org.simantics.interop.scl.Threads$SCLThread" where
+  data SCLThread
+  
+  isRunning :: SCLThread -> <Proc> Boolean
+  isCompleted :: SCLThread -> <Proc> Boolean
+  hasErrors :: SCLThread -> <Proc> Boolean
+  getReturnValue :: SCLThread -> <Proc> Maybe a
+  
+  
\ No newline at end of file
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;
+               }
+               
+       }
+
+}