From ef8da46af8ef42d04b9f0701f0d18e1277765d01 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 29 Oct 2010 03:30:25 +0200 Subject: Promoted the shutdown hook from GLDrawableFactoryImpl to GLProfile. Each GLDrawableFactory implementation provides a shutdownInstance() method, issued by GLProfile. --- .../jogamp/opengl/impl/GLDrawableFactoryImpl.java | 35 +--- .../jogamp/opengl/impl/egl/EGLDrawableFactory.java | 2 +- .../impl/macosx/cgl/MacOSXCGLDrawableFactory.java | 2 +- .../cgl/awt/MacOSXAWTCGLDrawableFactory.java | 5 - .../windows/wgl/WindowsWGLDrawableFactory.java | 3 +- .../opengl/impl/x11/glx/X11GLXDrawableFactory.java | 182 +++++++++++++++------ 6 files changed, 141 insertions(+), 88 deletions(-) (limited to 'src/jogl/classes/com') diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java index c0e554889..6837949d3 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java @@ -43,7 +43,6 @@ package com.jogamp.opengl.impl; import java.nio.*; import javax.media.nativewindow.*; import javax.media.opengl.*; -import java.security.*; /** Extends GLDrawableFactory with a few methods for handling typically software-accelerated offscreen rendering (Device @@ -53,6 +52,10 @@ import java.security.*; public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { protected static final boolean DEBUG = GLDrawableImpl.DEBUG; + protected GLDrawableFactoryImpl() { + super(); + } + /** * Returns the GLDynamicLookupHelper * @param profile if EGL/ES, profile 1 refers to ES1 and 2 to ES2, @@ -224,36 +227,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { // protected abstract GLDrawableImpl getSharedDrawable(); protected abstract GLContextImpl getSharedContext(); - protected abstract void shutdown(); - - // Shutdown hook mechanism for the factory - private boolean factoryShutdownHookRegistered; - private Thread factoryShutdownHook; - private synchronized void registerFactoryShutdownHook() { - if (factoryShutdownHookRegistered) - return; - if (factoryShutdownHook == null) { - factoryShutdownHook = new Thread(new Runnable() { - public void run() { - synchronized (GLDrawableFactoryImpl.this) { - shutdown(); - } - } - }); - } - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - Runtime.getRuntime().addShutdownHook(factoryShutdownHook); - return null; - } - }); - factoryShutdownHookRegistered = true; - } - - protected GLDrawableFactoryImpl() { - super(); - registerFactoryShutdownHook(); - } protected void maybeDoSingleThreadedWorkaround(Runnable action) { if (Threading.isSingleThreaded() && diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java index 83e85b922..deb659ddf 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java @@ -111,7 +111,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } } - protected void shutdown() {} + protected void shutdownInstance() {} protected final GLDrawableImpl getSharedDrawable() { return null; } protected final GLContextImpl getSharedContext() { return null; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java index 47e0e656f..f108ab327 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -84,7 +84,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { } catch (JogampRuntimeException jre) { /* n/a .. */ } } - protected void shutdown() {} + protected void shutdownInstance() {} protected final GLDrawableImpl getSharedDrawable() { return null; } protected final GLContextImpl getSharedContext() { return null; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java index eff01ca18..4a80990cb 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java @@ -39,13 +39,8 @@ package com.jogamp.opengl.impl.macosx.cgl.awt; -import java.lang.reflect.InvocationTargetException; -import java.nio.*; -import java.util.*; import javax.media.nativewindow.*; import javax.media.opengl.*; -import com.jogamp.opengl.impl.*; -import com.jogamp.opengl.impl.awt.*; import com.jogamp.opengl.impl.macosx.cgl.*; public class MacOSXAWTCGLDrawableFactory extends MacOSXCGLDrawableFactory { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index 409e914b0..f59fb78c9 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -43,7 +43,6 @@ package com.jogamp.opengl.impl.windows.wgl; import java.nio.*; import java.util.*; import javax.media.nativewindow.*; -import javax.media.nativewindow.windows.*; import javax.media.opengl.*; import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; @@ -118,7 +117,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return sharedContext; } - protected void shutdown() { + protected void shutdownInstance() { if (DEBUG) { System.err.println("!!! Shutdown Shared:"); System.err.println("!!! CTX : "+sharedContext); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 2828a90f1..82f57f33e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -82,38 +82,11 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } catch (JogampRuntimeException jre) { /* n/a .. */ } // init shared resources .. + sharedResourcesRunner = new SharedResourcesRunner(); + sharedResourcesThread = new Thread(sharedResourcesRunner, Thread.currentThread().getName()+"-SharedResourcesRunner"); + sharedResourcesThread.start(); + sharedResourcesRunner.waitUntilInitialized(); - long tlsDisplay = X11Util.createThreadLocalDisplay(null); - X11Util.lockDefaultToolkit(tlsDisplay); // OK - try { - X11GraphicsDevice sharedDevice = new X11GraphicsDevice(tlsDisplay); - vendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); - isVendorATI = GLXUtil.isVendorATI(vendorName); - isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); - sharedScreen = new X11GraphicsScreen(sharedDevice, 0); - sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault()); - if(isVendorATI() && GLProfile.isAWTAvailable()) { - X11Util.markThreadLocalDisplayUncloseable(tlsDisplay); // failure to close with ATI and AWT usage - } - if(null==sharedScreen || null==sharedDrawable) { - throw new GLException("Couldn't init shared screen("+sharedScreen+")/drawable("+sharedDrawable+")"); - } - // We have to keep this within this thread, - // since we have a 'chicken-and-egg' problem otherwise on the lock of this thread. - try{ - X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null); - ctx.makeCurrent(); - ctx.release(); - sharedContext = ctx; - } catch (Throwable t) { - throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t); - } - if(null==sharedContext) { - throw new GLException("X11GLXDrawableFactory - Shared Context is null"); - } - } finally { - X11Util.unlockDefaultToolkit(tlsDisplay); // OK - } if (DEBUG) { System.err.println("!!! Vendor: "+vendorName+", ATI: "+isVendorATI+", NV: "+isVendorNVIDIA); System.err.println("!!! SharedScreen: "+sharedScreen); @@ -121,7 +94,124 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } } - private X11GraphicsScreen sharedScreen; + class SharedResourcesRunner implements Runnable { + boolean initialized = false; + boolean released = false; + boolean shouldRelease = false; + + public void waitUntilInitialized() { + synchronized (this) { + while (!this.initialized) { + try { + this.wait(); + } catch (InterruptedException ex) { + } + } + } + } + + public void releaseAndWait() { + synchronized (this) { + this.shouldRelease = true; + this.notifyAll(); + + while (!this.released) { + try { + this.wait(); + } catch (InterruptedException ex) { + } + } + } + } + + public void run() { + String threadName = Thread.currentThread().getName(); + synchronized (this) { + if (DEBUG) { + System.err.println(threadName+ " initializing START"); + } + long tlsDisplay = X11Util.createDisplay(null); + X11Util.lockDefaultToolkit(tlsDisplay); // OK + try { + X11GraphicsDevice sharedDevice = new X11GraphicsDevice(tlsDisplay); + vendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); + isVendorATI = GLXUtil.isVendorATI(vendorName); + isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); + sharedScreen = new X11GraphicsScreen(sharedDevice, 0); + sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault()); + /* if(isVendorATI() && GLProfile.isAWTAvailable()) { + X11Util.markDisplayUncloseable(tlsDisplay); // failure to close with ATI and AWT usage + } */ + if (null == sharedScreen || null == sharedDrawable) { + throw new GLException("Couldn't init shared screen(" + sharedScreen + ")/drawable(" + sharedDrawable + ")"); + } + // We have to keep this within this thread, + // since we have a 'chicken-and-egg' problem otherwise on the lock of this thread. + try { + X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null); + ctx.makeCurrent(); + ctx.release(); + sharedContext = ctx; + } catch (Throwable t) { + throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t); + } + if (null == sharedContext) { + throw new GLException("X11GLXDrawableFactory - Shared Context is null"); + } + } finally { + X11Util.unlockDefaultToolkit(tlsDisplay); // OK + } + + if (DEBUG) { + System.err.println(threadName+ " initializing DONE"); + } + initialized = true; + notifyAll(); + } + + if (DEBUG) { + System.err.println(threadName+ " release WAIT"); + } + + synchronized(this) { + while (!this.shouldRelease) { + try { + this.wait(); + } catch (InterruptedException ex) { + } + } + if (DEBUG) { + System.err.println(threadName+ " release START"); + } + if (null != sharedContext) { + // may cause JVM SIGSEGV: sharedContext.destroy(); + sharedContext = null; + } + + if (null != sharedDrawable) { + // may cause JVM SIGSEGV: sharedDrawable.destroy(); + sharedDrawable = null; + } + if (null != sharedScreen) { + // may cause JVM SIGSEGV: + X11Util.closeDisplay(sharedScreen.getDevice().getHandle()); + sharedScreen = null; + } + + if (DEBUG) { + System.err.println(threadName+ " release END"); + } + released = true; + notifyAll(); + } + } + } + + Thread sharedResourcesThread = null; + SharedResourcesRunner sharedResourcesRunner=null; + private X11GraphicsScreen sharedScreen=null; + private X11DummyGLXDrawable sharedDrawable=null; + private X11GLXContext sharedContext=null; private String vendorName; private boolean isVendorATI; private boolean isVendorNVIDIA; @@ -130,9 +220,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { protected boolean isVendorATI() { return isVendorATI; } protected boolean isVendorNVIDIA() { return isVendorNVIDIA; } - private X11DummyGLXDrawable sharedDrawable=null; - private X11GLXContext sharedContext=null; - protected final GLDrawableImpl getSharedDrawable() { return sharedDrawable; } @@ -141,7 +228,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return sharedContext; } - protected void shutdown() { + protected void shutdownInstance() { if (DEBUG) { System.err.println("!!! Shutdown Shared:"); System.err.println("!!! CTX : "+sharedContext); @@ -149,22 +236,21 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { System.err.println("!!! Screen : "+sharedScreen); } - // don't free native resources from this point on, - // since we might be in a critical shutdown hook sequence + // may cause JVM SIGSEGV ? + // X11Util.closePendingDisplayConnections(); - if(null!=sharedContext) { - // may cause deadlock: sharedContext.destroy(); - sharedContext=null; - } + sharedResourcesRunner.releaseAndWait(); - if(null!=sharedDrawable) { - // may cause deadlock: sharedDrawable.destroy(); - sharedDrawable=null; + if(X11Util.getOpenDisplayConnectionNumber() > 0) { + System.err.println("X11GLXDrawableFactory.shutdown(): Open (no close attempt) X11 Display Connection"); + X11Util.dumpOpenDisplayConnections(); } - if(null!=sharedScreen) { - // may cause deadlock: X11Util.closeThreadLocalDisplay(sharedScreen.getDevice().getHandle()); - sharedScreen = null; + + if(X11Util.getPendingDisplayConnectionNumber()>0) { + System.err.println("X11GLXDrawableFactory.shutdown(): Pending X11 Display Connection"); + X11Util.dumpPendingDisplayConnections(); } + // don't close pending XDisplay, since this might be a different thread as the opener X11Util.shutdown( false, DEBUG ); } -- cgit v1.2.3