package org.simantics.modeling.scl;
import java.io.IOException;
+import java.util.List;
import java.util.Map;
-import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadFactory;
import org.simantics.scl.runtime.SCLContext;
import org.simantics.scl.runtime.function.Function;
import org.simantics.scl.runtime.tuple.Tuple0;
-import org.simantics.simulator.variable.NodeManager;
import org.simantics.simulator.variable.Realm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public static final String SCL = "scl";
- THashMap<String,Type> contextTypes = new THashMap<String,Type>();
+ private THashMap<String,Type> contextTypes = new THashMap<String,Type>();
- CommandSession connection;
- String id;
- Thread executorThread;
- ExecutorService executor = new ThreadPoolExecutor(0, 1, 60, TimeUnit.SECONDS,
- new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- executorThread = new Thread(r);
- return executorThread;
- }
- });
+ private CommandSession connection;
+ private String id;
+ private Thread executorThread;
+ private SCLRealmThreadFactory factory = new SCLRealmThreadFactory(this);
+ private ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 1, 60, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>(), factory);
- Semaphore beginSyncExec = new Semaphore(0);
- Semaphore endSyncExec = new Semaphore(0);
+ private Semaphore beginSyncExec = new Semaphore(0);
+ private Semaphore endSyncExec = new Semaphore(0);
- SCLNodeManager nodeManager;
+ private SCLNodeManager nodeManager;
- Runnable scheduleSyncExec = new Runnable() {
+ private Runnable scheduleSyncExec = new Runnable() {
@Override
public void run() {
beginSyncExec.release();
SCLSessionManager.CONNECTIONS.remove(id);
executor.shutdown();
try {
- executor.awaitTermination(500L, TimeUnit.MILLISECONDS);
+ if (!executor.awaitTermination(500L, TimeUnit.MILLISECONDS)) {
+ List<Runnable> runnables = executor.shutdownNow();
+ if (!runnables.isEmpty()) {
+ LOGGER.info("Some runnables left to execute in realm " + this + ": " + runnables);
+ }
+ }
} catch (InterruptedException e) {
+ LOGGER.info("Could not shutdown executor " + executor + " in realm " + this, e);
}
//connection.close();
+
+ factory.clear();
+ factory = null;
+ // Should not happen
+ if (executorThread.isAlive())
+ executorThread.interrupt();
+ executorThread = null;
+ executor = null;
+
+ // clear nodeManager
+ nodeManager.clear();
}
- public NodeManager<String> getNodeManager() {
+ public SCLNodeManager getNodeManager() {
return nodeManager;
}
}
}
+ private static class SCLRealmThreadFactory implements ThreadFactory {
+
+ private SCLRealm realm;
+
+ public SCLRealmThreadFactory(SCLRealm realm) {
+ this.realm = realm;
+ }
+
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r);
+ realm.setThread(t);
+ return t;
+ }
+
+ void clear() {
+ realm = null;
+ }
+ }
+
+ private void setThread(Thread t) {
+ this.executorThread = t;
+ }
}