diff options
Diffstat (limited to 'src/java/jogamp/common/util/locks')
4 files changed, 109 insertions, 62 deletions
diff --git a/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java b/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java index c930dff..1286924 100644 --- a/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java +++ b/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.AbstractOwnableSynchronizer; +import com.jogamp.common.util.SourcedInterruptedException; import com.jogamp.common.util.locks.RecursiveLock; /** @@ -197,7 +198,7 @@ public class RecursiveLockImpl01CompleteFair implements RecursiveLock { } catch (final InterruptedException e) { if( !wCur.signaledByUnlock ) { sync.queue.remove(wCur); // O(n) - throw e; // propagate interruption not send by unlock + throw SourcedInterruptedException.wrap(e); // propagate interruption not send by unlock } else if( cur != sync.getOwner() ) { // Issued by unlock, but still locked by other thread // @@ -215,6 +216,7 @@ public class RecursiveLockImpl01CompleteFair implements RecursiveLock { } // else: Issued by unlock, owning lock .. expected! } } while ( cur != sync.getOwner() && 0 < timeout ) ; + Thread.interrupted(); // clear slipped interrupt if( 0 >= timeout && cur != sync.getOwner() ) { // timed out diff --git a/src/java/jogamp/common/util/locks/RecursiveThreadGroupLockImpl01Unfairish.java b/src/java/jogamp/common/util/locks/RecursiveThreadGroupLockImpl01Unfairish.java index 77f73d8..fc5f739 100644 --- a/src/java/jogamp/common/util/locks/RecursiveThreadGroupLockImpl01Unfairish.java +++ b/src/java/jogamp/common/util/locks/RecursiveThreadGroupLockImpl01Unfairish.java @@ -42,6 +42,7 @@ public class RecursiveThreadGroupLockImpl01Unfairish threadNum = 0; threads = null; holdCountAdditionOwner = 0; + waitingOrigOwner = null; } @Override public final void incrHoldCount(final Thread t) { @@ -64,6 +65,12 @@ public class RecursiveThreadGroupLockImpl01Unfairish public final boolean isOriginalOwner(final Thread t) { return super.isOwner(t); } + public final void setWaitingOrigOwner(final Thread origOwner) { + waitingOrigOwner = origOwner; + } + public final Thread getWaitingOrigOwner() { + return waitingOrigOwner; + } @Override public final boolean isOwner(final Thread t) { if(getExclusiveOwnerThread()==t) { @@ -133,6 +140,7 @@ public class RecursiveThreadGroupLockImpl01Unfairish private int holdCountAdditionOwner; private Thread[] threads; private int threadNum; + private Thread waitingOrigOwner; } public RecursiveThreadGroupLockImpl01Unfairish() { @@ -157,10 +165,10 @@ public class RecursiveThreadGroupLockImpl01Unfairish final Thread cur = Thread.currentThread(); final ThreadGroupSync tgSync = (ThreadGroupSync)sync; if(!tgSync.isOriginalOwner(cur)) { - throw new IllegalArgumentException("Current thread is not the original owner: orig-owner: "+tgSync.getOwner()+", current "+cur); + throw new IllegalArgumentException("Current thread is not the original owner: orig-owner: "+tgSync.getOwner()+", current "+cur+": "+toString()); } if(tgSync.isOriginalOwner(t)) { - throw new IllegalArgumentException("Passed thread is original owner: "+t); + throw new IllegalArgumentException("Passed thread is original owner: "+t+", "+toString()); } tgSync.addOwner(t); } @@ -179,19 +187,25 @@ public class RecursiveThreadGroupLockImpl01Unfairish // original locking owner thread if( tgSync.getHoldCount() - tgSync.getAdditionalOwnerHoldCount() == 1 ) { // release orig. lock - while ( tgSync.getAdditionalOwnerHoldCount() > 0 ) { - try { - sync.wait(); - } catch (final InterruptedException e) { - // regular wake up! + tgSync.setWaitingOrigOwner(cur); + try { + while ( tgSync.getAdditionalOwnerHoldCount() > 0 ) { + try { + sync.wait(); + } catch (final InterruptedException e) { + // regular wake up! + } } + } finally { + tgSync.setWaitingOrigOwner(null); + Thread.interrupted(); // clear slipped interrupt } tgSync.removeAllOwners(); } } else if( tgSync.getAdditionalOwnerHoldCount() == 1 ) { - // last additional owner thread wakes up original owner - final Thread originalOwner = tgSync.getOwner(); - if(originalOwner.getState() == Thread.State.WAITING) { + // last additional owner thread wakes up original owner if waiting in unlock(..) + final Thread originalOwner = tgSync.getWaitingOrigOwner(); + if( null != originalOwner ) { originalOwner.interrupt(); } } diff --git a/src/java/jogamp/common/util/locks/SingletonInstanceFileLock.java b/src/java/jogamp/common/util/locks/SingletonInstanceFileLock.java index 44a5d28..9fe7966 100644 --- a/src/java/jogamp/common/util/locks/SingletonInstanceFileLock.java +++ b/src/java/jogamp/common/util/locks/SingletonInstanceFileLock.java @@ -32,6 +32,8 @@ import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileLock; + +import com.jogamp.common.util.InterruptSource; import com.jogamp.common.util.locks.SingletonInstance; public class SingletonInstanceFileLock extends SingletonInstance { @@ -76,7 +78,7 @@ public class SingletonInstanceFileLock extends SingletonInstance { private void setupFileCleanup() { file.deleteOnExit(); - Runtime.getRuntime().addShutdownHook(new Thread() { + Runtime.getRuntime().addShutdownHook(new InterruptSource.Thread() { @Override public void run() { if(isLocked()) { diff --git a/src/java/jogamp/common/util/locks/SingletonInstanceServerSocket.java b/src/java/jogamp/common/util/locks/SingletonInstanceServerSocket.java index b1b42c3..6219b5c 100644 --- a/src/java/jogamp/common/util/locks/SingletonInstanceServerSocket.java +++ b/src/java/jogamp/common/util/locks/SingletonInstanceServerSocket.java @@ -33,10 +33,16 @@ import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; + +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.common.util.locks.SingletonInstance; public class SingletonInstanceServerSocket extends SingletonInstance { + private static int serverInstanceCount = 0; private final Server singletonServer; private final String fullName; @@ -71,7 +77,7 @@ public class SingletonInstanceServerSocket extends SingletonInstance { fullName = ilh.toString()+":"+portNumber; singletonServer = new Server(ilh, portNumber); - Runtime.getRuntime().addShutdownHook(new Thread() { + Runtime.getRuntime().addShutdownHook(new InterruptSource.Thread() { @Override public void run() { singletonServer.kill(); @@ -139,38 +145,58 @@ public class SingletonInstanceServerSocket extends SingletonInstance { public final boolean start() { if(alive) return true; + final String sname; + synchronized (Server.class) { + serverInstanceCount++; + sname = "SingletonServerSocket"+serverInstanceCount+"-"+fullName; + } synchronized (syncOnStartStop) { - serverThread = new Thread(this); + shallQuit = false; + serverThread = new InterruptSource.Thread(null, this, sname); serverThread.setDaemon(true); // be a daemon, don't keep the JVM running serverThread.start(); try { - syncOnStartStop.wait(); + while( !alive && !shallQuit ) { + syncOnStartStop.wait(); + } } catch (final InterruptedException ie) { - ie.printStackTrace(); + final InterruptedException ie2 = SourcedInterruptedException.wrap(ie); + shutdown(false); + throw new InterruptedRuntimeException(ie2); } } final boolean ok = isBound(); if(!ok) { - shutdown(); + shutdown(true); } return ok; } public final boolean shutdown() { + return shutdown(true); + } + private final boolean shutdown(final boolean wait) { if(!alive) return true; - synchronized (syncOnStartStop) { - shallQuit = true; - connect(); - try { - syncOnStartStop.wait(); - } catch (final InterruptedException ie) { - ie.printStackTrace(); + try { + synchronized (syncOnStartStop) { + shallQuit = true; + connect(); + if( wait ) { + try { + while( alive ) { + syncOnStartStop.wait(); + } + } catch (final InterruptedException ie) { + throw new InterruptedRuntimeException(ie); + } + } + } + } finally { + if(alive) { + System.err.println(infoPrefix()+" EEE "+getName()+" - Unable to remove lock: ServerThread still alive ?"); + kill(); } - } - if(alive) { - System.err.println(infoPrefix()+" EEE "+getName()+" - Unable to remove lock: ServerThread still alive ?"); - kill(); } return true; } @@ -185,7 +211,8 @@ public class SingletonInstanceServerSocket extends SingletonInstance { System.err.println(infoPrefix()+" XXX "+getName()+" - Kill @ JVM Shutdown"); } alive = false; - if(null != serverThread) { + shallQuit = false; + if(null != serverThread && serverThread.isAlive() ) { try { serverThread.stop(); } catch(final Throwable t) { } @@ -214,47 +241,49 @@ public class SingletonInstanceServerSocket extends SingletonInstance { @Override public void run() { - { - final Thread currentThread = Thread.currentThread(); - currentThread.setName(currentThread.getName() + " - SISock: "+getName()); - if(DEBUG) { - System.err.println(currentThread.getName()+" - started"); - } + if(DEBUG) { + System.err.println(infoPrefix()+" III - Start"); } - alive = false; - synchronized (syncOnStartStop) { - try { - serverSocket = new ServerSocket(portNumber, 1, localInetAddress); - serverSocket.setReuseAddress(true); // reuse same port w/ subsequent instance, i.e. overcome TO state when JVM crashed - alive = true; - } catch (final IOException e) { - System.err.println(infoPrefix()+" III - Unable to install ServerSocket: "+e.getMessage()); - shallQuit = true; - } finally { - syncOnStartStop.notifyAll(); + try { + synchronized (syncOnStartStop) { + try { + serverSocket = new ServerSocket(portNumber, 1, localInetAddress); + serverSocket.setReuseAddress(true); // reuse same port w/ subsequent instance, i.e. overcome TO state when JVM crashed + alive = true; + } catch (final IOException e) { + System.err.println(infoPrefix()+" III - Unable to install ServerSocket: "+e.getMessage()); + shallQuit = true; + } finally { + syncOnStartStop.notifyAll(); + } } - } - while (!shallQuit) { - try { - final Socket clientSocket = serverSocket.accept(); - clientSocket.close(); - } catch (final IOException ioe) { - System.err.println(infoPrefix()+" EEE - Exception during accept: " + ioe.getMessage()); + while (!shallQuit) { + try { + final Socket clientSocket = serverSocket.accept(); + clientSocket.close(); + } catch (final IOException ioe) { + System.err.println(infoPrefix()+" EEE - Exception during accept: " + ioe.getMessage()); + } } - } - - synchronized (syncOnStartStop) { - try { + } catch(final ThreadDeath td) { + if( DEBUG ) { + ExceptionUtils.dumpThrowable("", td); + } + } finally { + synchronized (syncOnStartStop) { + if(DEBUG) { + System.err.println(infoPrefix()+" III - Stopping: alive "+alive+", shallQuit "+shallQuit+", hasSocket "+(null!=serverSocket)); + } if(null != serverSocket) { - serverSocket.close(); + try { + serverSocket.close(); + } catch (final IOException e) { + System.err.println(infoPrefix()+" EEE - Exception during close: " + e.getMessage()); + } } - } catch (final IOException e) { - System.err.println(infoPrefix()+" EEE - Exception during close: " + e.getMessage()); - } finally { serverSocket = null; alive = false; - shallQuit = false; syncOnStartStop.notifyAll(); } } |