1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.named.support;
20
21 import java.util.ArrayDeque;
22 import java.util.Collections;
23 import java.util.Deque;
24 import java.util.Map;
25 import java.util.concurrent.ConcurrentHashMap;
26 import java.util.concurrent.TimeUnit;
27
28 import org.eclipse.aether.named.NamedLock;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32
33
34
35 public abstract class NamedLockSupport implements NamedLock {
36 protected final Logger logger = LoggerFactory.getLogger(getClass());
37
38 private final String name;
39
40 private final NamedLockFactorySupport factory;
41
42 private final ConcurrentHashMap<Thread, Deque<String>> diagnosticState;
43
44 public NamedLockSupport(final String name, final NamedLockFactorySupport factory) {
45 this.name = name;
46 this.factory = factory;
47 this.diagnosticState = factory.isDiagnosticEnabled() ? new ConcurrentHashMap<>() : null;
48 }
49
50 @Override
51 public String name() {
52 return name;
53 }
54
55 @Override
56 public boolean lockShared(long time, TimeUnit unit) throws InterruptedException {
57 Deque<String> steps = null;
58 if (diagnosticState != null) {
59 steps = diagnosticState.computeIfAbsent(Thread.currentThread(), k -> new ArrayDeque<>());
60 }
61 if (steps != null) {
62 steps.push("wait-shared");
63 }
64 boolean result = doLockShared(time, unit);
65 if (steps != null) {
66 steps.pop();
67 if (result) {
68 steps.push("shared");
69 }
70 }
71 return result;
72 }
73
74 protected abstract boolean doLockShared(long time, TimeUnit unit) throws InterruptedException;
75
76 @Override
77 public boolean lockExclusively(long time, TimeUnit unit) throws InterruptedException {
78 Deque<String> steps = null;
79 if (diagnosticState != null) {
80 steps = diagnosticState.computeIfAbsent(Thread.currentThread(), k -> new ArrayDeque<>());
81 }
82 if (steps != null) {
83 steps.push("wait-exclusive");
84 }
85 boolean result = doLockExclusively(time, unit);
86 if (steps != null) {
87 steps.pop();
88 if (result) {
89 steps.push("exclusive");
90 }
91 }
92 return result;
93 }
94
95 protected abstract boolean doLockExclusively(long time, TimeUnit unit) throws InterruptedException;
96
97 @Override
98 public void unlock() {
99 doUnlock();
100 if (diagnosticState != null) {
101 diagnosticState
102 .computeIfAbsent(Thread.currentThread(), k -> new ArrayDeque<>())
103 .pop();
104 }
105 }
106
107 protected abstract void doUnlock();
108
109 @Override
110 public void close() {
111 doClose();
112 }
113
114 protected void doClose() {
115 factory.closeLock(name);
116 }
117
118
119
120
121
122
123 public Map<Thread, Deque<String>> diagnosticState() {
124 if (diagnosticState != null) {
125 return diagnosticState;
126 } else {
127 return Collections.emptyMap();
128 }
129 }
130
131 @Override
132 public String toString() {
133 return getClass().getSimpleName() + "{" + "name='" + name + '\'' + '}';
134 }
135 }