8316337: (bf) Concurrency issue in DirectByteBuffer.Deallocator

Reviewed-by: alanb, liach
This commit is contained in:
Per Minborg 2023-09-19 13:10:51 +00:00
parent 4461eeb31d
commit cf74b8c2a3
3 changed files with 31 additions and 45 deletions

View file

@ -75,31 +75,15 @@ class Direct$Type$Buffer$RW$$BO$
#if[byte]
private static class Deallocator
implements Runnable
{
private long address;
private long size;
private int capacity;
private Deallocator(long address, long size, int capacity) {
assert (address != 0);
this.address = address;
this.size = size;
this.capacity = capacity;
private record Deallocator(long address, long size, int capacity) implements Runnable {
private Deallocator {
assert address != 0;
}
public void run() {
if (address == 0) {
// Paranoia
return;
}
UNSAFE.freeMemory(address);
address = 0;
Bits.unreserveMemory(size, capacity);
}
}
private final Cleaner cleaner;

View file

@ -116,11 +116,16 @@ public abstract sealed class MappedByteBuffer
}
UnmapperProxy unmapper() {
return fd != null ?
new UnmapperProxy() {
return fd == null
? null
: new UnmapperProxy() {
// Ensure safe publication as MappedByteBuffer.this.address is not final
private final long addr = address;
@Override
public long address() {
return address;
return addr;
}
@Override
@ -137,7 +142,7 @@ public abstract sealed class MappedByteBuffer
public void unmap() {
Unsafe.getUnsafe().invokeCleaner(MappedByteBuffer.this);
}
} : null;
};
}
/**

View file

@ -1154,10 +1154,10 @@ public class FileChannelImpl
// -- Memory-mapped buffers --
private abstract static class Unmapper
private sealed abstract static class Unmapper
implements Runnable, UnmapperProxy
{
private volatile long address;
private final long address;
protected final long size;
protected final long cap;
private final FileDescriptor fd;
@ -1194,10 +1194,7 @@ public class FileChannelImpl
}
public void unmap() {
if (address == 0)
return;
nd.unmap(address, size);
address = 0;
// if this mapping has a valid file descriptor then we close it
if (fd.valid()) {
@ -1214,7 +1211,7 @@ public class FileChannelImpl
protected abstract void decrementStats();
}
private static class DefaultUnmapper extends Unmapper {
private static final class DefaultUnmapper extends Unmapper {
// keep track of non-sync mapped buffer usage
static volatile int count;
@ -1247,7 +1244,7 @@ public class FileChannelImpl
}
}
private static class SyncUnmapper extends Unmapper {
private static final class SyncUnmapper extends Unmapper {
// keep track of mapped buffer usage
static volatile int count;