}
public static void asyncRead(final Function f) throws DatabaseException {
- final SCLContext context = SCLContext.getCurrent();
- Object graph = context.get(GRAPH);
- if (graph != null) {
- f.apply(Tuple0.INSTANCE);
- } else {
- Simantics.getSession().asyncRequest(new ReadRequest() {
- @Override
- public void run(ReadGraph graph) throws DatabaseException {
- SCLContext.push(context);
- ReadGraph oldGraph = (ReadGraph)context.put(GRAPH, graph);
- try {
- f.apply(Tuple0.INSTANCE);
- } finally {
- context.put(GRAPH, oldGraph);
- SCLContext.pop();
- }
+ final SCLContext context = SCLContext.createDerivedContext();
+ Simantics.getSession().asyncRequest(new ReadRequest() {
+ @Override
+ public void run(ReadGraph graph) throws DatabaseException {
+ SCLContext.push(context);
+ context.put(GRAPH, graph);
+ try {
+ f.apply(Tuple0.INSTANCE);
+ } finally {
+ SCLContext.pop();
}
- });
- }
+ }
+ });
}
public static <T> T syncRead(final Function f) throws DatabaseException {
}
public static void asyncWrite(final Function f) throws DatabaseException {
- final SCLContext context = SCLContext.getCurrent();
- Object graph = context.get(GRAPH);
- if (graph != null) {
- f.apply(Tuple0.INSTANCE);
- } else {
- Simantics.getSession().asyncRequest(new WriteRequest() {
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- SCLContext.push(context);
- ReadGraph oldGraph = (ReadGraph)context.put(GRAPH, graph);
- try {
- f.apply(Tuple0.INSTANCE);
- } finally {
- context.put(GRAPH, oldGraph);
- SCLContext.pop();
- }
+ SCLContext context = SCLContext.createDerivedContext();
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ SCLContext.push(context);
+ context.put(GRAPH, graph);
+ try {
+ f.apply(Tuple0.INSTANCE);
+ } finally {
+ SCLContext.pop();
}
- });
- }
+ }
+ });
}
public static <T> T syncWrite(final Function f) throws DatabaseException {
package org.simantics.scl.runtime;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
+
import gnu.trove.map.hash.THashMap;
public class SCLContext extends THashMap<String,Object> {
CONTEXT.set(newContext);
}
+ /**
+ * Creates a new context based on some properties of the current context.
+ * The new context is safe for use in parallel threads.
+ */
+ public static SCLContext createDerivedContext() {
+ SCLContext newContext = new SCLContext();
+
+ SCLContext baseContext = CONTEXT.get();
+ if(baseContext != null) {
+ Object reportingHandler = baseContext.get(SCLReportingHandler.REPORTING_HANDLER);
+ if(reportingHandler != null)
+ newContext.put(SCLReportingHandler.REPORTING_HANDLER, reportingHandler);
+ }
+ return newContext;
+ }
+
public static void pop() {
OldContextNode node = OLD_CONTEXT.get();
if(node == null)
package org.simantics.scl.runtime.utils;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
import org.simantics.scl.runtime.SCLContext;
import org.simantics.scl.runtime.function.Function;
+import org.simantics.scl.runtime.reporting.SCLReporting;
import org.simantics.scl.runtime.tuple.Tuple0;
public class AsyncUtils {
public static void runAsync(Function f) {
- SCLContext context = SCLContext.getCurrent();
+ SCLContext context = SCLContext.createDerivedContext();
new Thread() {
@Override
public void run() {
SCLContext.push(context);
try {
f.apply(Tuple0.INSTANCE);
+ } catch(Exception e) {
+ StringWriter sw = new StringWriter();
+ e.printStackTrace(new PrintWriter(sw));
+ SCLReporting.printError(sw.toString());
} finally {
SCLContext.pop();
}