1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
package com.jogamp.nativewindow.impl;
import javax.media.nativewindow.*;
//
// Reentrance locking toolkit
//
public class RecursiveToolkitLock {
private Thread owner = null;
private int recursionCount = 0;
private Exception lockedStack = null;
private static final long timeout = 3000; // maximum wait 3s
private static final boolean TRACE_LOCK = false;
public Exception getLockedStack() {
return lockedStack;
}
public Thread getOwner() {
return owner;
}
public boolean isOwner() {
return isOwner(Thread.currentThread());
}
public synchronized boolean isOwner(Thread thread) {
return owner == thread ;
}
public synchronized boolean isLocked() {
return null != owner;
}
public synchronized int getRecursionCount() {
return recursionCount;
}
public synchronized void validateLocked() {
if ( !isLocked() ) {
throw new RuntimeException(Thread.currentThread()+": Not locked");
}
if ( !isOwner() ) {
getLockedStack().printStackTrace();
throw new RuntimeException(Thread.currentThread()+": Not owner, owner is "+owner);
}
}
/** Recursive and blocking lockSurface() implementation */
public synchronized void lock() {
Thread cur = Thread.currentThread();
if(TRACE_LOCK) {
System.out.println("... LOCK 0 ["+this+"], recursions "+recursionCount+", "+cur);
}
if (owner == cur) {
++recursionCount;
if(TRACE_LOCK) {
System.out.println("+++ LOCK 1 ["+this+"], recursions "+recursionCount+", "+cur);
}
return;
}
long ts = System.currentTimeMillis();
while (owner != null && (System.currentTimeMillis()-ts) < timeout) {
try {
wait(timeout);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
if(owner != null) {
lockedStack.printStackTrace();
throw new RuntimeException("Waited "+timeout+"ms for: "+owner+" - "+cur+", with recursionCount "+recursionCount+", lock: "+this);
}
if(TRACE_LOCK) {
System.out.println("+++ LOCK X ["+this+"], recursions "+recursionCount+", "+cur);
}
owner = cur;
lockedStack = new Exception("Previously locked by "+owner+", lock: "+this);
}
/** Recursive and unblocking unlockSurface() implementation */
public synchronized void unlock() {
unlock(null);
}
/** Recursive and unblocking unlockSurface() implementation */
public synchronized void unlock(Runnable taskAfterUnlockBeforeNotify) {
validateLocked();
if (recursionCount > 0) {
--recursionCount;
if(TRACE_LOCK) {
System.out.println("--- LOCK 1 ["+this+"], recursions "+recursionCount+", "+Thread.currentThread());
}
return;
}
owner = null;
lockedStack = null;
if(null!=taskAfterUnlockBeforeNotify) {
taskAfterUnlockBeforeNotify.run();
}
if(TRACE_LOCK) {
System.out.println("--- LOCK X ["+this+"], recursions "+recursionCount+", "+Thread.currentThread());
}
notifyAll();
}
}
|