diff options
Diffstat (limited to 'src/nativewindow/classes')
-rw-r--r-- | src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java | 98 |
1 files changed, 75 insertions, 23 deletions
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index b6a052253..bf37b8d0c 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -37,8 +37,10 @@ import java.io.File; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import jogamp.nativewindow.Debug; @@ -108,7 +110,9 @@ public abstract class NativeWindowFactory { private static boolean requiresToolkitLock; private static boolean desktopHasThreadingIssues; + // Shutdown hook mechanism for the factory private static volatile boolean isJVMShuttingDown = false; + private static final List<Runnable> customShutdownHooks = new ArrayList<Runnable>(); /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ @@ -160,6 +164,11 @@ public abstract class NativeWindowFactory { Platform.initSingleton(); // last resort .. _DEBUG[0] = Debug.debug("NativeWindow"); _tmp[0] = Debug.getProperty("nativewindow.ws.name", true); + Runtime.getRuntime().addShutdownHook( + new Thread(new Runnable() { + public void run() { + NativeWindowFactory.shutdown(true); + } }, "NativeWindowFactory_ShutdownHook" ) ) ; return null; } } ) ; @@ -204,6 +213,72 @@ public abstract class NativeWindowFactory { } } + /** Returns true if the JVM is shutting down, otherwise false. */ + public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; } + + /** + * Add a custom shutdown hook to be performed at JVM shutdown before shutting down NativeWindowFactory instance. + * + * @param head if true add runnable at the start, otherwise at the end + * @param runnable runnable to be added. + */ + public static void addCustomShutdownHook(boolean head, Runnable runnable) { + synchronized( customShutdownHooks ) { + if( !customShutdownHooks.contains( runnable ) ) { + if( head ) { + customShutdownHooks.add(0, runnable); + } else { + customShutdownHooks.add( runnable ); + } + } + } + } + + /** + * Cleanup resources at JVM shutdown + */ + public static synchronized void shutdown(boolean _isJVMShuttingDown) { + isJVMShuttingDown = _isJVMShuttingDown; + if(DEBUG) { + System.err.println("NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown+", on thread "+Thread.currentThread().getName()); + } + synchronized(customShutdownHooks) { + final int cshCount = customShutdownHooks.size(); + for(int i=0; i < cshCount; i++) { + try { + if( DEBUG ) { + System.err.println("NativeWindowFactory.shutdown - customShutdownHook #"+(i+1)+"/"+cshCount); + } + customShutdownHooks.get(i).run(); + } catch(Throwable t) { + System.err.println("NativeWindowFactory.shutdown: Catched "+t.getClass().getName()+" during customShutdownHook #"+(i+1)+"/"+cshCount); + if( DEBUG ) { + t.printStackTrace(); + } + } + } + customShutdownHooks.clear(); + } + if(DEBUG) { + System.err.println("NativeWindowFactory.shutdown(): Post customShutdownHook"); + } + + if(initialized) { + initialized = false; + if(null != registeredFactories) { + registeredFactories.clear(); + registeredFactories = null; + } + GraphicsConfigurationFactory.shutdown(); + } + + shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown + // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet + if(DEBUG) { + System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown); + } + } + private static void shutdownNativeImpl(final ClassLoader cl) { final String clazzName; if( TYPE_X11 == nativeWindowingTypePure ) { @@ -310,29 +385,6 @@ public abstract class NativeWindowFactory { } } - public static synchronized void shutdown(boolean _isJVMShuttingDown) { - isJVMShuttingDown = _isJVMShuttingDown; - if(DEBUG) { - System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown); - } - if(initialized) { - initialized = false; - if(null != registeredFactories) { - registeredFactories.clear(); - registeredFactories = null; - } - GraphicsConfigurationFactory.shutdown(); - } - shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown - // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet - if(DEBUG) { - System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown); - } - } - - /** Returns true if the JVM is shutting down, otherwise false. */ - public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; } - /** @return true if the underlying toolkit requires locking, otherwise false. */ public static boolean requiresToolkitLock() { return requiresToolkitLock; |