From db7ce1c9c271edf6dc08db9f920adc93df9b2bb0 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 5 Sep 2015 04:42:53 +0200 Subject: Bug 1213 - RecursiveThreadGroupLockImpl01Unfairish.unlock() always interrupts original-owner, even if not waiting at unlock() RecursiveThreadGroupLockImpl01Unfairish.unlock(): An interrupt() is always issued from group members on the original owner. This shall only happen, if the original owner is waiting within unlock() for all group members to be unlocked. This extra interrupt causes side-effects, see Bug 1211. Only issue the interrupt to wake-up the original owner iff waiting within unlock! +++ RecursiveLockImpl01CompleteFair: Issue 'Thread.interrupted()' to clear a slipped interrupt call after while-loop. --- .../locks/RecursiveLockImpl01CompleteFair.java | 1 + .../RecursiveThreadGroupLockImpl01Unfairish.java | 30 ++++++++++++++++------ 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'src/java') diff --git a/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java b/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java index c930dff..f86dd33 100644 --- a/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java +++ b/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java @@ -215,6 +215,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 abd79eb..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() { @@ -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(); } } -- cgit v1.2.3