diff options
author | Debian Java Maintainers <pkg-java-maintainers@lists.alioth.debian.org> | 2019-02-28 14:20:34 +0100 |
---|---|---|
committer | Andrej Shadura <andrewsh@debian.org> | 2019-02-28 14:20:34 +0100 |
commit | ae542e8a315b91ae4b52025a8822b1a4cb320abb (patch) | |
tree | e14058571852cf6a24707a466a658260cda47b15 | |
parent | 0d8ef144a9600f0cc689e7a63cc493cc76bad3f5 (diff) |
Gbp-Pq: Name java9.patch
-rwxr-xr-x | pom.xml | 12 | ||||
-rwxr-xr-x | src/main/java/net/openhft/chronicle/bytes/NativeBytesStore.java | 79 |
2 files changed, 77 insertions, 14 deletions
@@ -111,10 +111,16 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> - <compilerArgument>-Xlint:deprecation</compilerArgument> - <source>1.8</source> - <target>1.8</target> + <source>1.9</source> + <target>1.9</target> + <fork>true</fork> <encoding>UTF-8</encoding> + <compilerArgs> + <arg>-Xlint:deprecation</arg> + <arg>--add-exports=java.base/jdk.internal.ref=ALL-UNNAMED</arg> + <arg>--add-exports=java.base/sun.nio.ch=ALL-UNNAMED</arg> + <arg>--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED</arg> + </compilerArgs> </configuration> </plugin> <!-- diff --git a/src/main/java/net/openhft/chronicle/bytes/NativeBytesStore.java b/src/main/java/net/openhft/chronicle/bytes/NativeBytesStore.java index dc970df..b88ebca 100755 --- a/src/main/java/net/openhft/chronicle/bytes/NativeBytesStore.java +++ b/src/main/java/net/openhft/chronicle/bytes/NativeBytesStore.java @@ -19,17 +19,22 @@ package net.openhft.chronicle.bytes; import net.openhft.chronicle.core.*; import net.openhft.chronicle.core.annotation.ForceInline; import net.openhft.chronicle.core.io.IORuntimeException; +import net.openhft.chronicle.core.Jvm; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sun.misc.Cleaner; +import java.lang.ref.Cleaner; import sun.nio.ch.DirectBuffer; +import sun.misc.Unsafe; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.nio.BufferOverflowException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; +import java.security.AccessController; +import java.security.PrivilegedAction; @SuppressWarnings("sunapi") public class NativeBytesStore<Underlying> @@ -37,11 +42,22 @@ public class NativeBytesStore<Underlying> private static final long MEMORY_MAPPED_SIZE = 128 << 10; private static final Logger LOGGER = LoggerFactory.getLogger(NativeBytesStore.class); private static final Field BB_ADDRESS, BB_CAPACITY; + private static final Unsafe UNSAFE; + private static final Method invokeCleaner; static { Class directBB = ByteBuffer.allocateDirect(0).getClass(); BB_ADDRESS = Jvm.getField(directBB, "address"); BB_CAPACITY = Jvm.getField(directBB, "capacity"); + UNSAFE = getUnsafe(); + Method tmpCleaner; + try { + tmpCleaner = UNSAFE.getClass().getDeclaredMethod("invokeCleaner", ByteBuffer.class); + tmpCleaner.setAccessible(true); + } catch (Throwable t) { + tmpCleaner = null; + } + invokeCleaner = tmpCleaner; } @Nullable @@ -52,12 +68,13 @@ public class NativeBytesStore<Underlying> protected long address; long maximumLimit; @Nullable - private Cleaner cleaner; + private final static Cleaner cleaner = Cleaner.create(); + private Cleaner.Cleanable cleanable; private final ReferenceCounter refCount = ReferenceCounter.onReleased(this::performRelease); private boolean elastic; @Nullable private Underlying underlyingObject; - private Error releasedHere; + Error releasedHere; private NativeBytesStore() { } @@ -75,7 +92,11 @@ public class NativeBytesStore<Underlying> long address, long maximumLimit, @Nullable Runnable deallocator, boolean elastic) { setAddress(address); this.maximumLimit = maximumLimit; - cleaner = deallocator == null ? null : Cleaner.create(this, deallocator); + if (deallocator != null) { + cleanable = cleaner.register(this, deallocator); + } else { + cleanable = null; + } underlyingObject = null; this.elastic = elastic; } @@ -141,14 +162,27 @@ public class NativeBytesStore<Underlying> underlyingObject = (Underlying) bb; setAddress(((DirectBuffer) bb).address()); this.maximumLimit = bb.capacity(); - cleaner = ((DirectBuffer) bb).cleaner(); + if (invokeCleaner != null) { + cleanable = cleaner.register(this, new Runnable() { + @Override + public void run() { + try { + invokeCleaner.invoke(UNSAFE, bb); + } catch (Throwable e) { + + } + } + }); + } else { + cleanable = null; + } } public void uninit() { underlyingObject = null; address = 0; maximumLimit = 0; - cleaner = null; + cleanable = null; } @NotNull @@ -423,7 +457,7 @@ public class NativeBytesStore<Underlying> public void write( long offsetInRDO, @NotNull ByteBuffer bytes, int offset, int length) { if (bytes.isDirect()) { - memory.copyMemory(((DirectBuffer) bytes).address(), + memory.copyMemory(((DirectBuffer) bytes).address() + offset, address + translate(offsetInRDO), length); } else { @@ -450,19 +484,21 @@ public class NativeBytesStore<Underlying> @Override public long address(long offset) throws UnsupportedOperationException { - if (offset < start() || offset >= capacity()) + if (offset < start() || offset > capacity()) throw new IllegalArgumentException(); return address + translate(offset); } private void performRelease() { + memory = null; if (refCount.get() > 0) { LOGGER.info("NativeBytesStore discarded without releasing ", createdHere); } - memory = null; - if (cleaner != null) - cleaner.clean(); + if (releasedHere == null) + releasedHere = new Error(); + if (cleanable != null) + cleanable.clean(); } @NotNull @@ -626,4 +662,25 @@ public class NativeBytesStore<Underlying> } } + + private static Unsafe getUnsafe() { + if (System.getSecurityManager() != null) { + return AccessController.doPrivileged(new PrivilegedAction<Unsafe>() { + public Unsafe run() { + return getUnsafe0(); + } + }); + } + return getUnsafe0(); + } + + private static Unsafe getUnsafe0() { + try { + Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + return (Unsafe) theUnsafe.get(null); + } catch (Throwable t) { + throw new RuntimeException("JDK did not allow accessing unsafe", t); + } + } } |