summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDebian Java Maintainers <pkg-java-maintainers@lists.alioth.debian.org>2019-02-28 14:20:34 +0100
committerAndrej Shadura <andrewsh@debian.org>2019-02-28 14:20:34 +0100
commitae542e8a315b91ae4b52025a8822b1a4cb320abb (patch)
treee14058571852cf6a24707a466a658260cda47b15
parent0d8ef144a9600f0cc689e7a63cc493cc76bad3f5 (diff)
Gbp-Pq: Name java9.patch
-rwxr-xr-xpom.xml12
-rwxr-xr-xsrc/main/java/net/openhft/chronicle/bytes/NativeBytesStore.java79
2 files changed, 77 insertions, 14 deletions
diff --git a/pom.xml b/pom.xml
index e149729..c21d589 100755
--- a/pom.xml
+++ b/pom.xml
@@ -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);
+ }
+ }
}