feat: provide some information upon OverlappingFileLockException (#2341)

This commit is contained in:
Jordan 2023-07-10 22:16:05 +01:00 committed by GitHub
parent 1f29ab3b79
commit c0e20a6fe5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -39,6 +39,8 @@ import java.net.URI;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer; import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -46,6 +48,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* A clipboard with disk backed storage. (lower memory + loads on crash) * A clipboard with disk backed storage. (lower memory + loads on crash)
@ -59,6 +62,7 @@ public class DiskOptimizedClipboard extends LinearClipboard {
private static final int HEADER_SIZE = 27; // Current header size private static final int HEADER_SIZE = 27; // Current header size
private static final int VERSION_1_HEADER_SIZE = 22; // Header size of "version 1" private static final int VERSION_1_HEADER_SIZE = 22; // Header size of "version 1"
private static final int VERSION_2_HEADER_SIZE = 27; // Header size of "version 2" i.e. when NBT/entities could be saved private static final int VERSION_2_HEADER_SIZE = 27; // Header size of "version 2" i.e. when NBT/entities could be saved
private static final Map<String, LockHolder> LOCK_HOLDER_CACHE = new ConcurrentHashMap<>();
private final HashMap<IntTriple, CompoundTag> nbtMap; private final HashMap<IntTriple, CompoundTag> nbtMap;
private final File file; private final File file;
@ -301,7 +305,23 @@ public class DiskOptimizedClipboard extends LinearClipboard {
private void init() throws IOException { private void init() throws IOException {
if (this.fileChannel == null) { if (this.fileChannel == null) {
this.fileChannel = braf.getChannel(); this.fileChannel = braf.getChannel();
this.fileChannel.lock(); try {
FileLock lock = this.fileChannel.lock();
LOCK_HOLDER_CACHE.put(file.getName(), new LockHolder(lock));
} catch (OverlappingFileLockException e) {
LockHolder existing = LOCK_HOLDER_CACHE.get(file.getName());
if (existing != null) {
long ms = System.currentTimeMillis() - existing.lockHeldSince;
LOGGER.error(
"Cannot lock clipboard file {} acquired by thread {}, {}ms ago",
file.getName(),
existing.thread,
ms
);
}
// Rethrow to prevent clipboard access
throw e;
}
this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, braf.length()); this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, braf.length());
} }
} }
@ -737,4 +757,18 @@ public class DiskOptimizedClipboard extends LinearClipboard {
return false; return false;
} }
private static class LockHolder {
final FileLock lock;
final long lockHeldSince;
final String thread;
LockHolder(FileLock lock) {
this.lock = lock;
lockHeldSince = System.currentTimeMillis();
this.thread = Thread.currentThread().getName();
}
}
} }