diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/SharedResourceRunner.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/SharedResourceRunner.java | 136 |
1 files changed, 96 insertions, 40 deletions
diff --git a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java index 9b9093a87..0f6c1f875 100644 --- a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java +++ b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java @@ -28,14 +28,19 @@ package jogamp.opengl; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.Map; import com.jogamp.nativewindow.AbstractGraphicsDevice; import com.jogamp.nativewindow.AbstractGraphicsScreen; import com.jogamp.opengl.GLProfile; import com.jogamp.common.ExceptionUtils; +import com.jogamp.common.util.InterruptSource; +import com.jogamp.common.util.InterruptedRuntimeException; +import com.jogamp.common.util.SourcedInterruptedException; import com.jogamp.opengl.GLRendererQuirks; public class SharedResourceRunner implements Runnable { @@ -81,6 +86,29 @@ public class SharedResourceRunner implements Runnable { /** Called within synchronized block. */ Collection<Resource> mapValues(); } + public static abstract class AImplementation implements Implementation { + private final HashMap<String /* uniqueId */, SharedResourceRunner.Resource> sharedMap = new HashMap<String, SharedResourceRunner.Resource>(); + /** Called within synchronized block. Use w/ care! */ + public Map<String /* uniqueId */, SharedResourceRunner.Resource> getSharedMap() { + return sharedMap; + } + @Override + public final void clear() { + sharedMap.clear(); + } + @Override + public final SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) { + return sharedMap.put(device.getUniqueID(), resource); + } + @Override + public final SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) { + return sharedMap.get(device.getUniqueID()); + } + @Override + public final Collection<SharedResourceRunner.Resource> mapValues() { + return sharedMap.values(); + } + } final HashSet<String> devicesTried = new HashSet<String>(); final Implementation impl; @@ -93,13 +121,13 @@ public class SharedResourceRunner implements Runnable { AbstractGraphicsDevice releaseDevice; private boolean getDeviceTried(final AbstractGraphicsDevice device) { // synchronized call - return devicesTried.contains(device.getConnection()); + return devicesTried.contains(device.getUniqueID()); } private void addDeviceTried(final AbstractGraphicsDevice device) { // synchronized call - devicesTried.add(device.getConnection()); + devicesTried.add(device.getUniqueID()); } private void removeDeviceTried(final AbstractGraphicsDevice device) { // synchronized call - devicesTried.remove(device.getConnection()); + devicesTried.remove(device.getUniqueID()); } public SharedResourceRunner(final Implementation impl) { @@ -141,13 +169,18 @@ public class SharedResourceRunner implements Runnable { System.err.println("SharedResourceRunner.start() - start new Thread - "+getThreadName()); } resetState(); - thread = new Thread(this, getThreadName()+"-SharedResourceRunner"); + thread = new InterruptSource.Thread(null, this, getThreadName()+"-SharedResourceRunner"); thread.setDaemon(true); // Allow JVM to exit, even if this one is running thread.start(); - while (!running) { - try { + try { + while (!running) { this.wait(); - } catch (final InterruptedException ex) { } + } + } catch (final InterruptedException ex) { + // Cleanup + shouldRelease = true; + this.notifyAll(); + throw new InterruptedRuntimeException(ex); } } } @@ -163,11 +196,12 @@ public class SharedResourceRunner implements Runnable { synchronized (this) { shouldRelease = true; this.notifyAll(); - - while (running) { - try { + try { + while (running) { this.wait(); - } catch (final InterruptedException ex) { } + } + } catch (final InterruptedException ex) { + throw new InterruptedRuntimeException(ex); } } } @@ -188,7 +222,11 @@ public class SharedResourceRunner implements Runnable { ExceptionUtils.dumpStack(System.err); } if ( impl.isDeviceSupported(device) ) { - doAndWait(device, null); + try { + doAndWait(device, null); + } catch (final InterruptedException ex) { + throw new InterruptedRuntimeException(ex); + } sr = impl.mapGet(device); } if (DEBUG) { @@ -211,7 +249,11 @@ public class SharedResourceRunner implements Runnable { if (DEBUG) { System.err.println("SharedResourceRunner.releaseShared() " + device + ": trying - "+getThreadName()); } - doAndWait(null, device); + try { + doAndWait(null, device); + } catch (final InterruptedException ex) { + throw new InterruptedRuntimeException(ex); + } if (DEBUG) { System.err.println("SharedResourceRunner.releaseShared() " + device + ": done - "+getThreadName()); } @@ -221,7 +263,7 @@ public class SharedResourceRunner implements Runnable { return sr; } - private final void doAndWait(final AbstractGraphicsDevice initDevice, final AbstractGraphicsDevice releaseDevice) { + private final void doAndWait(final AbstractGraphicsDevice initDevice, final AbstractGraphicsDevice releaseDevice) throws InterruptedException { synchronized (this) { // wait until thread becomes ready to init new device, // pass the device and release the sync @@ -229,26 +271,41 @@ public class SharedResourceRunner implements Runnable { if (DEBUG) { System.err.println("SharedResourceRunner.doAndWait() START init: " + initDevice + ", release: "+releaseDevice+" - "+threadName); } - while (!ready && running) { - try { + try { + while (!ready && running) { this.wait(); - } catch (final InterruptedException ex) { } - } - if (DEBUG) { - System.err.println("SharedResourceRunner.doAndWait() set command: " + initDevice + ", release: "+releaseDevice+" - "+threadName); - } - this.initDevice = initDevice; - this.releaseDevice = releaseDevice; - this.notifyAll(); + } + if (DEBUG) { + System.err.println("SharedResourceRunner.doAndWait() set command: " + initDevice + ", release: "+releaseDevice+" - "+threadName); + } + this.initDevice = initDevice; + this.releaseDevice = releaseDevice; + this.notifyAll(); - // wait until thread has init/released the device - while ( running && ( !ready || null != this.initDevice || null != this.releaseDevice ) ) { - try { + // wait until thread has init/released the device + while ( running && ( !ready || null != this.initDevice || null != this.releaseDevice ) ) { this.wait(); - } catch (final InterruptedException ex) { } + } + } catch (final InterruptedException ex) { + final InterruptedException ex2 = SourcedInterruptedException.wrap(ex); + if (DEBUG) { + System.err.println("SharedResourceRunner.doAndWait() INTERRUPT init: " + initDevice + ", release: "+releaseDevice+" - "+threadName); + ExceptionUtils.dumpThrowable("", ex2); + } + // Cleanup initDevice due to exception! + final AbstractGraphicsDevice _initDevice = this.initDevice; + if( null != _initDevice ) { + if (DEBUG) { + System.err.println("SharedResourceRunner.doAndWait() Cleanup init: " + _initDevice + " -> release: "+this.releaseDevice+" - "+threadName); + } + this.releaseDevice = _initDevice; + this.initDevice = null; + this.notifyAll(); + } + throw ex2; } if (DEBUG) { - System.err.println("SharedResourceRunner.initializeAndWait END init: " + initDevice + ", release: "+releaseDevice+" - "+threadName); + System.err.println("SharedResourceRunner.doAndWait() END init: " + initDevice + ", release: "+releaseDevice+" - "+threadName); } } // done @@ -267,19 +324,18 @@ public class SharedResourceRunner implements Runnable { while (!shouldRelease) { try { - // wait for stop or init + // wait until call-thread issues stop or init/released a device ready = true; if (DEBUG) { System.err.println("SharedResourceRunner.run(): READY - " + threadName); } notifyAll(); - this.wait(); + while ( !shouldRelease && null == initDevice && null == releaseDevice ) { + this.wait(); + } } catch (final InterruptedException ex) { shouldRelease = true; - if(DEBUG) { - System.err.println("SharedResourceRunner.run(): INTERRUPTED - "+threadName); - ex.printStackTrace(); - } + ExceptionUtils.dumpThrowable("handled", SourcedInterruptedException.wrap(ex)); // cancelable } ready = false; @@ -296,7 +352,7 @@ public class SharedResourceRunner implements Runnable { try { sr = impl.createSharedResource(initDevice); } catch (final Exception e) { - e.printStackTrace(); + ExceptionUtils.dumpThrowable("handled", e); } if (null != sr) { impl.mapPut(initDevice, sr); @@ -310,9 +366,10 @@ public class SharedResourceRunner implements Runnable { if (null != sr) { try { impl.releaseSharedResource(sr); - impl.mapPut(releaseDevice, null); } catch (final Exception e) { - e.printStackTrace(); + ExceptionUtils.dumpThrowable("handled", e); + } finally { + impl.mapPut(releaseDevice, null); } } } @@ -345,8 +402,7 @@ public class SharedResourceRunner implements Runnable { try { impl.releaseSharedResource(iter.next()); } catch (final Throwable t) { - System.err.println("Caught exception on thread "+getThreadName()); - t.printStackTrace(); + ExceptionUtils.dumpThrowable("", t); } } impl.clear(); |