+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;
+ }
+
+ }
+
+}