diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/SharedResourceRunner.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/SharedResourceRunner.java | 220 |
1 files changed, 126 insertions, 94 deletions
diff --git a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java index 0528d3060..283ecdb9d 100644 --- a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java +++ b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java @@ -33,27 +33,49 @@ import java.util.Iterator; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; +import com.jogamp.opengl.GLRendererQuirks; + public class SharedResourceRunner implements Runnable { protected static final boolean DEBUG = GLDrawableImpl.DEBUG; public static interface Resource { + boolean isValid(); AbstractGraphicsDevice getDevice(); AbstractGraphicsScreen getScreen(); GLDrawableImpl getDrawable(); GLContextImpl getContext(); + GLRendererQuirks getRendererQuirks(); } public static interface Implementation { /** - * @param connection for creation a {@link AbstractGraphicsDevice} instance. - * @return A new shared resource instance + * <p> + * Called within synchronized block. + * </p> + * @param connection for creation a {@link AbstractGraphicsDevice} instance. + * @return <code>true</code> if the device supports all protocols required for the implementation, otherwise <code>false</code>. + */ + boolean isDeviceSupported(String connection); + + /** + * <p> + * Called within synchronized block. + * </p> + * @param connection for creation a {@link AbstractGraphicsDevice} instance. + * @return A new shared resource instance */ Resource createSharedResource(String connection); + + /** Called within synchronized block. */ void releaseSharedResource(Resource shared); + /** Called within synchronized block. */ void clear(); + /** Called within synchronized block. */ Resource mapPut(String connection, Resource resource); + /** Called within synchronized block. */ Resource mapGet(String connection); + /** Called within synchronized block. */ Collection<Resource> mapValues(); } @@ -61,106 +83,115 @@ public class SharedResourceRunner implements Runnable { final Implementation impl; Thread thread; + boolean running; boolean ready; - boolean released; boolean shouldRelease; String initConnection; String releaseConnection; - private boolean getDeviceTried(String connection) { - synchronized (devicesTried) { - return devicesTried.contains(connection); - } + private boolean getDeviceTried(String connection) { // synchronized call + return devicesTried.contains(connection); } - private void addDeviceTried(String connection) { - synchronized (devicesTried) { - devicesTried.add(connection); - } + private void addDeviceTried(String connection) { // synchronized call + devicesTried.add(connection); } - private void removeDeviceTried(String connection) { - synchronized (devicesTried) { - devicesTried.remove(connection); - } + private void removeDeviceTried(String connection) { // synchronized call + devicesTried.remove(connection); } public SharedResourceRunner(Implementation impl) { this.impl = impl; resetState(); } - - private void resetState() { + + private void resetState() { // synchronized call devicesTried.clear(); thread = null; ready = false; - released = false; + running = false; shouldRelease = false; initConnection = null; releaseConnection = null; } - /** + /** * Start the shared resource runner thread, if not running. * <p> * Validate the thread upfront and release all related resource if it was killed. * </p> - * + * * @return the shared resource runner thread. */ public Thread start() { - if(null != thread && !thread.isAlive()) { - // thread was killed unrecognized .. - if (DEBUG) { - System.err.println("SharedResourceRunner.start() - dead-old-thread cleanup - "+Thread.currentThread().getName()); + synchronized (this) { + if(null != thread && !thread.isAlive()) { + // thread was killed unrecognized .. + if (DEBUG) { + System.err.println("SharedResourceRunner.start() - dead-old-thread cleanup - "+getThreadName()); + } + releaseSharedResources(); + thread = null; + running = false; } - releaseSharedResources(); - thread = null; - } - if(null == thread) { - if (DEBUG) { - System.err.println("SharedResourceRunner.start() - start new Thread - "+Thread.currentThread().getName()); + if( null == thread ) { + if (DEBUG) { + System.err.println("SharedResourceRunner.start() - start new Thread - "+getThreadName()); + } + resetState(); + thread = new Thread(this, getThreadName()+"-SharedResourceRunner"); + thread.setDaemon(true); // Allow JVM to exit, even if this one is running + thread.start(); + while (!running) { + try { + this.wait(); + } catch (InterruptedException ex) { } + } } - resetState(); - thread = new Thread(this, Thread.currentThread().getName()+"-SharedResourceRunner"); - thread.setDaemon(true); // Allow JVM to exit, even if this one is running - thread.start(); } return thread; } - + public void stop() { - if(null != thread) { - if (DEBUG) { - System.err.println("SharedResourceRunner.stop() - "+Thread.currentThread().getName()); - } - synchronized (this) { - shouldRelease = true; - this.notifyAll(); - - while (!released) { - try { - this.wait(); - } catch (InterruptedException ex) { + synchronized (this) { + if(null != thread) { + if (DEBUG) { + System.err.println("SharedResourceRunner.stop() - "+getThreadName()); + } + synchronized (this) { + shouldRelease = true; + this.notifyAll(); + + while (running) { + try { + this.wait(); + } catch (InterruptedException ex) { } } } } } } - + public SharedResourceRunner.Resource getOrCreateShared(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = null; if(null != device) { - start(); - final String connection = device.getConnection(); - sr = impl.mapGet(connection); - if (null == sr && !getDeviceTried(connection)) { - addDeviceTried(connection); - if (DEBUG) { - System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": trying - "+Thread.currentThread().getName()); - } - doAndWait(connection, null); + synchronized (this) { + start(); + final String connection = device.getConnection(); sr = impl.mapGet(connection); - if (DEBUG) { - System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": "+ ( ( null != sr ) ? "success" : "failed" ) +" - "+Thread.currentThread().getName()); + if (null == sr) { + if ( !getDeviceTried(connection) ) { + addDeviceTried(connection); + if (DEBUG) { + System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": trying - "+getThreadName()); + } + if ( impl.isDeviceSupported(connection) ) { + doAndWait(connection, null); + sr = impl.mapGet(connection); + } + if (DEBUG) { + System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": "+ ( ( null != sr ) ? "success" : "failed" ) +" - "+getThreadName()); + } + } } } } @@ -170,16 +201,18 @@ public class SharedResourceRunner implements Runnable { public SharedResourceRunner.Resource releaseShared(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = null; if(null != device) { - String connection = device.getConnection(); - sr = impl.mapGet(connection); - if (null != sr) { - removeDeviceTried(connection); - if (DEBUG) { - System.err.println("SharedResourceRunner.releaseShared() " + connection + ": trying - "+Thread.currentThread().getName()); - } - doAndWait(null, connection); - if (DEBUG) { - System.err.println("SharedResourceRunner.releaseShared() " + connection + ": done - "+Thread.currentThread().getName()); + synchronized (this) { + final String connection = device.getConnection(); + sr = impl.mapGet(connection); + if (null != sr) { + removeDeviceTried(connection); + if (DEBUG) { + System.err.println("SharedResourceRunner.releaseShared() " + connection + ": trying - "+getThreadName()); + } + doAndWait(null, connection); + if (DEBUG) { + System.err.println("SharedResourceRunner.releaseShared() " + connection + ": done - "+getThreadName()); + } } } } @@ -187,18 +220,17 @@ public class SharedResourceRunner implements Runnable { } private final void doAndWait(String initConnection, String releaseConnection) { - // wait until thread becomes ready to init new device, - // pass the device and release the sync - final String threadName = Thread.currentThread().getName(); - if (DEBUG) { - System.err.println("SharedResourceRunner.doAndWait() START init: " + initConnection + ", release: "+releaseConnection+" - "+threadName); - } synchronized (this) { - while (!ready) { + // wait until thread becomes ready to init new device, + // pass the device and release the sync + final String threadName = getThreadName(); + if (DEBUG) { + System.err.println("SharedResourceRunner.doAndWait() START init: " + initConnection + ", release: "+releaseConnection+" - "+threadName); + } + while (!ready && running) { try { this.wait(); - } catch (InterruptedException ex) { - } + } catch (InterruptedException ex) { } } if (DEBUG) { System.err.println("SharedResourceRunner.doAndWait() set command: " + initConnection + ", release: "+releaseConnection+" - "+threadName); @@ -208,11 +240,10 @@ public class SharedResourceRunner implements Runnable { this.notifyAll(); // wait until thread has init/released the device - while (!ready || null != this.initConnection || null != this.releaseConnection) { + while ( running && ( !ready || null != this.initConnection || null != this.releaseConnection ) ) { try { this.wait(); - } catch (InterruptedException ex) { - } + } catch (InterruptedException ex) { } } if (DEBUG) { System.err.println("SharedResourceRunner.initializeAndWait END init: " + initConnection + ", release: "+releaseConnection+" - "+threadName); @@ -221,14 +252,17 @@ public class SharedResourceRunner implements Runnable { // done } + @Override public final void run() { - final String threadName = Thread.currentThread().getName(); + final String threadName = getThreadName(); if (DEBUG) { System.err.println("SharedResourceRunner.run(): STARTED - " + threadName); } synchronized (this) { + running = true; + while (!shouldRelease) { try { // wait for stop or init @@ -238,10 +272,10 @@ public class SharedResourceRunner implements Runnable { } notifyAll(); this.wait(); - } catch (InterruptedException ex) { + } catch (InterruptedException ex) { shouldRelease = true; if(DEBUG) { - System.err.println("SharedResourceRunner.run(): INTERRUPTED - "+Thread.currentThread().getName()); + System.err.println("SharedResourceRunner.run(): INTERRUPTED - "+threadName); ex.printStackTrace(); } } @@ -260,9 +294,7 @@ public class SharedResourceRunner implements Runnable { try { sr = impl.createSharedResource(initConnection); } catch (Exception e) { - if(DEBUG) { - e.printStackTrace(); - } + e.printStackTrace(); } if (null != sr) { impl.mapPut(initConnection, sr); @@ -280,7 +312,7 @@ public class SharedResourceRunner implements Runnable { } catch (Exception e) { e.printStackTrace(); } - } + } } } initConnection = null; @@ -298,25 +330,25 @@ public class SharedResourceRunner implements Runnable { } shouldRelease = false; - released = true; + running = false; thread = null; notifyAll(); } } - private void releaseSharedResources() { - synchronized (devicesTried) { - devicesTried.clear(); - } + private void releaseSharedResources() { // synchronized call + devicesTried.clear(); Collection<Resource> sharedResources = impl.mapValues(); for (Iterator<Resource> iter = sharedResources.iterator(); iter.hasNext();) { try { impl.releaseSharedResource(iter.next()); } catch (Throwable t) { - System.err.println("Catched Exception: "+t.getStackTrace()+" - "+Thread.currentThread().getName()); + System.err.println("Catched Exception on thread "+getThreadName()); t.printStackTrace(); } } impl.clear(); } + + protected static String getThreadName() { return Thread.currentThread().getName(); } } |