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"
--- /dev/null
+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
--- /dev/null
+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;
+ }
+
+ }
+
+}