1 package org.eclipse.aether.named.support;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.eclipse.aether.named.NamedLockFactory;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import java.util.Objects;
27 import java.util.concurrent.ConcurrentHashMap;
28 import java.util.concurrent.ConcurrentMap;
29 import java.util.concurrent.atomic.AtomicInteger;
30
31
32
33
34 public abstract class NamedLockFactorySupport
35 implements NamedLockFactory
36 {
37 protected final Logger logger = LoggerFactory.getLogger( getClass() );
38
39 private final ConcurrentMap<String, NamedLockHolder> locks;
40
41 public NamedLockFactorySupport()
42 {
43 this.locks = new ConcurrentHashMap<>();
44 }
45
46 @Override
47 public NamedLockSupport getLock( final String name )
48 {
49 return locks.compute( name, ( k, v ) ->
50 {
51 if ( v == null )
52 {
53 v = new NamedLockHolder( createLock( k ) );
54 }
55 v.incRef();
56 return v;
57 } ).namedLock;
58 }
59
60 @Override
61 public void shutdown()
62 {
63
64 }
65
66 public void closeLock( final String name )
67 {
68 locks.compute( name, ( k, v ) ->
69 {
70 if ( v != null && v.decRef() == 0 )
71 {
72 destroyLock( v.namedLock.name() );
73 return null;
74 }
75 return v;
76 } );
77 }
78
79
80 @Override
81 protected void finalize() throws Throwable
82 {
83 try
84 {
85 if ( !locks.isEmpty() )
86 {
87
88 logger.warn( "Lock leak, referenced locks still exist {}", locks );
89 }
90 }
91 finally
92 {
93 super.finalize();
94 }
95 }
96
97
98
99
100
101 protected abstract NamedLockSupport createLock( final String name );
102
103
104
105
106
107 protected void destroyLock( final String name )
108 {
109
110 }
111
112 private static final class NamedLockHolder
113 {
114 private final NamedLockSupport namedLock;
115
116 private final AtomicInteger referenceCount;
117
118 private NamedLockHolder( final NamedLockSupport namedLock )
119 {
120 this.namedLock = Objects.requireNonNull( namedLock );
121 this.referenceCount = new AtomicInteger( 0 );
122 }
123
124 private int incRef()
125 {
126 return referenceCount.incrementAndGet();
127 }
128
129 private int decRef()
130 {
131 return referenceCount.decrementAndGet();
132 }
133
134 @Override
135 public String toString()
136 {
137 return "[refCount=" + referenceCount.get() + ", lock=" + namedLock + "]";
138 }
139 }
140 }