Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions src/com/sun/jna/NativeMappedConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,39 @@

import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/** Provides type conversion for instances of {@link NativeMapped}. */
public class NativeMappedConverter implements TypeConverter {
private static final ReentrantReadWriteLock mapLock = new ReentrantReadWriteLock();
private static final Map<Class<?>, Reference<NativeMappedConverter>> converters =
new WeakHashMap<>();
private final Class<?> type;
private final Class<?> nativeType;
private final NativeMapped instance;

public static NativeMappedConverter getInstance(Class<?> cls) {
synchronized(converters) {
Reference<NativeMappedConverter> r = converters.get(cls);
NativeMappedConverter nmc = r != null ? r.get() : null;
if (nmc == null) {
nmc = new NativeMappedConverter(cls);
converters.put(cls, new SoftReference<>(nmc));
mapLock.readLock().lock();
try {
Reference<NativeMappedConverter> ref = converters.get(cls);
if (ref != null) {
return ref.get();
}
return nmc;
} finally {
mapLock.readLock().unlock();
}

mapLock.writeLock().lock();
try {
return converters.computeIfAbsent(cls, (clz) -> {
NativeMappedConverter nmc = new NativeMappedConverter(cls);
return new SoftReference<>(nmc);
}).get();
}
finally {
mapLock.writeLock().unlock();
}
}

Expand Down
Loading