1
1
/* ###
2
2
* IP: GHIDRA
3
- * REVIEWED: YES
4
3
*
5
4
* Licensed under the Apache License, Version 2.0 (the "License");
6
5
* you may not use this file except in compliance with the License.
17
16
package ghidra .util ;
18
17
19
18
/**
20
- * Ghidra synchronization lock. This class allows creation of named locks for
21
- * modifying tables in the Ghidra data base. This class also creates an instance
22
- * of a global lock that must first be obtained when synchronizing using multiple
23
- * of the named locks.
19
+ * Ghidra synchronization lock. This class allows creation of named locks for
20
+ * synchroniing modification of multiple tables in the Ghidra database.
24
21
*/
25
22
public class Lock {
26
23
private Thread owner ;
27
- private int cnt = 0 ;
24
+ private int lockAquireCount = 0 ;
25
+ private int waiterCount = 0 ;
28
26
private String name ;
29
27
30
28
/**
31
29
* Creates an instance of a lock for synchronization within Ghidra.
30
+ *
32
31
* @param name the name of this lock
33
32
*/
34
33
public Lock (String name ) {
35
34
this .name = name ;
36
35
}
37
36
38
37
/**
39
- * Acquire this synchronization lock.
40
- * (i.e. begin synchronizing on this named lock.)
38
+ * Acquire this synchronization lock. (i.e. begin synchronizing on this named
39
+ * lock.)
41
40
*/
42
41
public synchronized void acquire () {
43
42
Thread currThread = Thread .currentThread ();
44
43
45
44
while (true ) {
46
45
if (owner == null ) {
47
- cnt = 1 ;
46
+ lockAquireCount = 1 ;
48
47
owner = currThread ;
49
48
return ;
50
49
}
51
50
else if (owner == currThread ) {
52
- cnt ++;
51
+ lockAquireCount ++;
53
52
return ;
54
53
}
55
54
try {
55
+ waiterCount ++;
56
56
wait ();
57
57
}
58
58
catch (InterruptedException e ) {
59
+ // exception from another threads notify(), ignore
60
+ // and try to get lock again
61
+ }
62
+ finally {
63
+ waiterCount --;
59
64
}
60
65
}
61
66
}
@@ -67,10 +72,15 @@ else if (owner == currThread) {
67
72
public synchronized void release () {
68
73
Thread currThread = Thread .currentThread ();
69
74
70
- if (cnt > 0 && (owner == currThread )) {
71
- if (--cnt == 0 ) {
75
+ if (lockAquireCount > 0 && (owner == currThread )) {
76
+ if (--lockAquireCount == 0 ) {
72
77
owner = null ;
73
- notify ();
78
+ // This is purely to help sample profiling. If notify() is called the
79
+ // sampler can attribute time to the methods calling this erroneously. For some reason
80
+ // the visualvm sampler gets a sample more often when notify() is called.
81
+ if (waiterCount != 0 ) {
82
+ notify ();
83
+ }
74
84
}
75
85
}
76
86
else {
@@ -80,10 +90,10 @@ public synchronized void release() {
80
90
81
91
/**
82
92
* Gets the thread that currently owns the lock.
93
+ *
83
94
* @return the thread that owns the lock or null.
84
95
*/
85
96
public Thread getOwner () {
86
97
return owner ;
87
98
}
88
-
89
99
}
0 commit comments