diff truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/TruffleVM.java @ 22183:1421041175a7

Adding dispose() and TruffleLanguage.disposeContext to allow user request and languages explicitly free the resources
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Mon, 21 Sep 2015 14:05:33 +0200
parents 0480c4873a4a
children 2e7352f9ffa8
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/TruffleVM.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/TruffleVM.java	Mon Sep 21 14:05:33 2015 +0200
@@ -110,6 +110,7 @@
     private final EventConsumer<?>[] handlers;
     private final Map<String, Object> globals;
     private Debugger debugger;
+    private boolean disposed;
 
     /**
      * Private & temporary only constructor.
@@ -443,6 +444,35 @@
         return eval(l, source);
     }
 
+    /**
+     * Dispose instance of this engine. A user can explicitly
+     * {@link TruffleLanguage#disposeContext(java.lang.Object) dispose all resources} allocated by
+     * the languages active in this engine, when it is known the system is not going to be used in
+     * the future.
+     * <p>
+     * Calling any other method of this class after the dispose has been done yields an
+     * {@link IllegalStateException}.
+     */
+    public void dispose() {
+        checkThread();
+        disposed = true;
+        executor.execute(new Runnable() {
+            @Override
+            public void run() {
+                for (Language language : getLanguages().values()) {
+                    TruffleLanguage<?> impl = language.getImpl(false);
+                    if (impl != null) {
+                        try {
+                            SPI.dispose(impl, language.getEnv(true));
+                        } catch (Exception | Error ex) {
+                            LOG.log(Level.SEVERE, "Error disposing " + impl, ex);
+                        }
+                    }
+                }
+            }
+        });
+    }
+
     private Symbol eval(final Language l, final Source s) throws IOException {
         final Debugger[] fillIn = {debugger};
         final Object[] result = {null, null};
@@ -549,6 +579,9 @@
         if (initThread != Thread.currentThread()) {
             throw new IllegalStateException("TruffleVM created on " + initThread.getName() + " but used on " + Thread.currentThread().getName());
         }
+        if (disposed) {
+            throw new IllegalStateException("Engine has already been disposed");
+        }
     }
 
     @SuppressWarnings("unchecked")
@@ -930,5 +963,10 @@
             TruffleVM vm = (TruffleVM) obj;
             vm.dispatch(event);
         }
+
+        @Override
+        protected void dispose(TruffleLanguage<?> impl, TruffleLanguage.Env env) {
+            super.dispose(impl, env);
+        }
     } // end of SPIAccessor
 }