27package jau.test.util.parallel.locks.impl;
30import java.util.concurrent.locks.AbstractOwnableSynchronizer;
32import jau.test.util.parallel.locks.RecursiveLock;
46 static interface Sync {
49 void setOwner(Thread t);
52 void setLockedStack(Throwable s);
55 void incrHoldCount(Thread t);
56 void decrHoldCount(Thread t);
63 @SuppressWarnings(
"serial")
64 static class SingleThreadSync
extends AbstractOwnableSynchronizer implements Sync {
70 return getExclusiveOwnerThread();
73 public boolean isOwner(
final Thread t) {
74 return getExclusiveOwnerThread()==t;
77 public final void setOwner(
final Thread t) {
78 setExclusiveOwnerThread(t);
85 public final void setLockedStack(
final Throwable s) {
88 ls.remove(lockedStack);
97 public void incrHoldCount(
final Thread t) { holdCount++; }
99 public void decrHoldCount(
final Thread t) { holdCount--; }
102 public final int getQSz() {
return qsz; }
104 public final void incrQSz() { qsz++; }
106 public final void decrQSz() { qsz--; }
109 private int holdCount = 0;
113 private Throwable lockedStack =
null;
123 this(
new SingleThreadSync());
133 return sync.getLockedStack();
140 return sync.getOwner();
145 public final boolean isOwner(
final Thread thread) {
147 return sync.isOwner(thread);
154 return null !=
sync.getOwner();
161 final Thread o =
sync.getOwner();
162 return null != o && Thread.currentThread() != o ;
169 return sync.getHoldCount();
176 if ( !
sync.isOwner(Thread.currentThread()) ) {
177 if (
null ==
sync.getOwner() ) {
178 throw new RuntimeException(threadName(Thread.currentThread())+
": Not locked: "+
toString());
180 if(
null!=
sync.getLockedStack()) {
181 sync.getLockedStack().printStackTrace();
183 throw new RuntimeException(Thread.currentThread()+
": Not owner: "+
toString());
193 if(
null!=
sync.getLockedStack()) {
194 sync.getLockedStack().printStackTrace();
196 throw new RuntimeException(
"Waited "+
TIMEOUT+
"ms for: "+
toString()+
" - "+threadName(Thread.currentThread()));
198 }
catch (
final InterruptedException e) {
199 throw new RuntimeException(
"Interrupted", e);
205 public final boolean tryLock(
long timeout)
throws InterruptedException {
207 final Thread cur = Thread.currentThread();
209 System.err.println(
"+++ LOCK 0 "+
toString()+
", timeout "+timeout+
" ms, cur "+threadName(cur));
211 if (
sync.isOwner(cur)) {
212 sync.incrHoldCount(cur);
214 System.err.println(
"+++ LOCK XR "+
toString()+
", cur "+threadName(cur));
219 if (
sync.getOwner() !=
null || ( 0<timeout && 0<
sync.getQSz() ) ) {
221 if ( 0 >= timeout ) {
224 System.err.println(
"+++ LOCK XY "+
toString()+
", cur "+threadName(cur)+
", left "+timeout+
" ms");
231 final long t0 = System.currentTimeMillis();
233 timeout -= System.currentTimeMillis() - t0;
234 }
while (
null !=
sync.getOwner() && 0 < timeout) ;
237 if( 0 >= timeout &&
sync.getOwner() != null ) {
240 System.err.println(
"+++ LOCK XX "+
toString()+
", cur "+threadName(cur)+
", left "+timeout+
" ms");
246 System.err.println(
"+++ LOCK X1 "+
toString()+
", cur "+threadName(cur)+
", left "+timeout+
" ms");
249 System.err.println(
"+++ LOCK X0 "+
toString()+
", cur "+threadName(cur));
253 sync.incrHoldCount(cur);
256 sync.setLockedStack(
new Throwable(
"Previously locked by "+
toString()));
271 public void unlock(
final Runnable taskAfterUnlockBeforeNotify) {
274 final Thread cur = Thread.currentThread();
276 sync.decrHoldCount(cur);
278 if (
sync.getHoldCount() > 0) {
280 System.err.println(
"--- LOCK XR "+
toString()+
", cur "+threadName(cur));
287 sync.setLockedStack(
null);
289 if(
null!=taskAfterUnlockBeforeNotify) {
290 taskAfterUnlockBeforeNotify.run();
294 System.err.println(
"--- LOCK X0 "+
toString()+
", cur "+threadName(cur)+
", signal any");
303 return sync.getQSz();
309 return syncName()+
"[count "+
sync.getHoldCount()+
310 ", qsz "+
sync.getQSz()+
", owner "+threadName(
sync.getOwner())+
"]";
313 final String syncName() {
314 return "<"+Integer.toHexString(this.hashCode())+
", "+Integer.toHexString(
sync.hashCode())+
">";
316 final String threadName(
final Thread t) {
return null!=t ?
"<"+t.getName()+
">" :
"<NULL>" ; }
Functionality enabled if Lock#DEBUG is true.
static List< Throwable > getRecursiveLockTrace()
Reentrance locking toolkit, impl a non-complete fair FIFO scheduler.
final boolean tryLock(long timeout)
Blocking until the lock is acquired by this Thread or maxwait in ms is reached.
RecursiveLockImpl01Unfairish()
final void validateLocked()
void unlock(final Runnable taskAfterUnlockBeforeNotify)
Execute the Runnable taskAfterUnlockBeforeNotify while holding the exclusive lock.
final void unlock()
Release the lock.
final boolean isOwner(final Thread thread)
Query whether the lock is hold by the given thread.
final Throwable getLockedStack()
Returns the Throwable instance generated when this lock was taken the 1st time and if jau....
final boolean isLocked()
Query if locked.
final int getHoldCount()
Return the number of locks issued to this lock by the same thread.
final void lock()
Blocking until the lock is acquired by this Thread or TIMEOUT is reached.
RecursiveLockImpl01Unfairish(final Sync sync)
final int getQueueLength()
final boolean isLockedByOtherThread()
Query whether the lock is hold by the a thread other than the current thread.
static final long TIMEOUT
The TIMEOUT for lock() in ms, defaults to DEFAULT_TIMEOUT.
static final boolean DEBUG
Enable via the property jogamp.debug.Lock
static final boolean TRACE_LOCK
Enable via the property jogamp.debug.Lock.TraceLock
Reentrance capable locking toolkit.