mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
8316337: (bf) Concurrency issue in DirectByteBuffer.Deallocator
Reviewed-by: alanb, liach
This commit is contained in:
parent
4461eeb31d
commit
cf74b8c2a3
3 changed files with 31 additions and 45 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue