summaryrefslogtreecommitdiff
path: root/debian/patches/cleaner.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/cleaner.patch')
-rw-r--r--debian/patches/cleaner.patch271
1 files changed, 271 insertions, 0 deletions
diff --git a/debian/patches/cleaner.patch b/debian/patches/cleaner.patch
new file mode 100644
index 0000000..a5f06c7
--- /dev/null
+++ b/debian/patches/cleaner.patch
@@ -0,0 +1,271 @@
+Bug-Debian: https://bugs.debian.org/893495
+Bug-Debian: https://bugs.debian.org/917727
+Forwarded: no
+Last-Update: 2019-02-28
+
+--- a/lang/src/main/java/net/openhft/lang/io/AbstractMappedStore.java
++++ b/lang/src/main/java/net/openhft/lang/io/AbstractMappedStore.java
+@@ -28,7 +28,7 @@
+
+ import net.openhft.lang.io.serialization.ObjectSerializer;
+ import net.openhft.lang.model.constraints.NotNull;
+-import sun.misc.Cleaner;
++import java.lang.ref.Cleaner;
+ import sun.nio.ch.FileChannelImpl;
+
+ abstract class AbstractMappedStore implements BytesStore, Closeable {
+@@ -39,7 +39,8 @@
+ // retain to prevent GC.
+ private final File file;
+ private final RandomAccessFile raf;
+- private final Cleaner cleaner;
++ private final static Cleaner cleaner = Cleaner.create();
++ private Cleaner.Cleanable cleanable;
+ private final AtomicInteger refCount = new AtomicInteger(1);
+ private final FileChannel.MapMode mode;
+ protected final MmapInfoHolder mmapInfoHolder;
+@@ -59,7 +60,7 @@
+ this.raf = new RandomAccessFile(file, accesModeFor(mode));
+ resizeIfNeeded(startInFile, size);
+ map(startInFile);
+- this.cleaner = Cleaner.create(this, new Unmapper(mmapInfoHolder, raf));
++ this.cleanable = cleaner.register(this, new Unmapper(mmapInfoHolder, raf));
+ } catch (Exception e) {
+ throw wrap(e);
+ }
+@@ -173,7 +174,7 @@
+
+ @Override
+ public final void free() {
+- cleaner.clean();
++ cleanable.clean();
+ }
+
+ @Override
+--- a/lang/src/main/java/net/openhft/lang/io/ByteBufferReuse.java
++++ b/lang/src/main/java/net/openhft/lang/io/ByteBufferReuse.java
+@@ -117,12 +117,15 @@
+
+ final byte[] impl = cw.toByteArray();
+
+- final Unsafe unsafe = NativeBytes.UNSAFE;
+ Class clazz = AccessController.doPrivileged(new PrivilegedAction<Class>() {
+ @Override
+ public Class run() {
+ ClassLoader cl = MAGIC_CLASS_LOADER;
+- return unsafe.defineClass(reuseImplClassName, impl, 0, impl.length, cl, null);
++ try {
++ return (Class) NativeBytes.defineClassMethodHandle.bindTo(cl).invokeWithArguments(reuseImplClassName, impl, 0, impl.length);
++ } catch (Throwable e) {
++ throw new RuntimeException(e);
++ }
+ }
+ });
+ try {
+--- a/lang/src/main/java/net/openhft/lang/io/CharBufferReuse.java
++++ b/lang/src/main/java/net/openhft/lang/io/CharBufferReuse.java
+@@ -102,12 +102,15 @@
+
+ final byte[] impl = cw.toByteArray();
+
+- final Unsafe unsafe = NativeBytes.UNSAFE;
+ Class clazz = AccessController.doPrivileged(new PrivilegedAction<Class>() {
+ @Override
+ public Class run() {
+ ClassLoader cl = MAGIC_CLASS_LOADER;
+- return unsafe.defineClass(reuseImplClassName, impl, 0, impl.length, cl, null);
++ try {
++ return (Class) NativeBytes.defineClassMethodHandle.bindTo(cl).invokeWithArguments(reuseImplClassName, impl, 0, impl.length);
++ } catch (Throwable e) {
++ throw new RuntimeException(e);
++ }
+ }
+ });
+ try {
+--- a/lang/src/main/java/net/openhft/lang/io/DirectStore.java
++++ b/lang/src/main/java/net/openhft/lang/io/DirectStore.java
+@@ -22,7 +22,7 @@
+ import net.openhft.lang.io.serialization.ObjectSerializer;
+ import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory;
+ import net.openhft.lang.model.constraints.NotNull;
+-import sun.misc.Cleaner;
++import java.lang.ref.Cleaner;
+
+ import java.io.File;
+ import java.util.concurrent.atomic.AtomicInteger;
+@@ -32,7 +32,8 @@
+ */
+ public class DirectStore implements BytesStore, AutoCloseable {
+ private final ObjectSerializer objectSerializer;
+- private final Cleaner cleaner;
++ private final static Cleaner cleaner = Cleaner.create();
++ private Cleaner.Cleanable cleanable;
+ private final Deallocator deallocator;
+ private long address;
+ private long size;
+@@ -62,7 +63,7 @@
+
+ this.size = size;
+ deallocator = new Deallocator(address);
+- cleaner = Cleaner.create(this, deallocator);
++ cleanable = cleaner.register(this, deallocator);
+ }
+
+ @Override
+@@ -123,7 +124,7 @@
+ }
+
+ public void free() {
+- cleaner.clean();
++ cleanable.clean();
+ }
+
+ public long size() {
+--- a/lang/src/main/java/net/openhft/lang/io/IOTools.java
++++ b/lang/src/main/java/net/openhft/lang/io/IOTools.java
+@@ -19,8 +19,8 @@
+ import net.openhft.lang.model.constraints.NotNull;
+ import net.openhft.lang.model.constraints.Nullable;
+ import org.slf4j.LoggerFactory;
+-import sun.misc.Cleaner;
+ import sun.nio.ch.DirectBuffer;
++import sun.misc.Unsafe;
+
+ import java.io.Closeable;
+ import java.io.File;
+@@ -28,6 +28,8 @@
+ import java.nio.ByteBuffer;
+ import java.nio.charset.Charset;
+
++import java.lang.reflect.Method;
++
+ /**
+ * @author peter.lawrey
+ */
+@@ -35,6 +37,19 @@
+ ;
+ public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+ public static final Charset UTF_8 = Charset.forName("UTF-8");
++ private static final Unsafe unsafe = NativeBytes.UNSAFE;
++ private static final Method invokeCleaner;
++
++ static {
++ Method tmpCleaner;
++ try {
++ tmpCleaner = unsafe.getClass().getDeclaredMethod("invokeCleaner", ByteBuffer.class);
++ tmpCleaner.setAccessible(true);
++ } catch (Throwable t) {
++ tmpCleaner = null;
++ }
++ invokeCleaner = tmpCleaner;
++ }
+
+ public static void close(@Nullable Closeable closeable) {
+ if (closeable == null) return;
+@@ -82,9 +97,13 @@
+
+ public static void clean(ByteBuffer bb) {
+ if (bb instanceof DirectBuffer) {
+- Cleaner cl = ((DirectBuffer) bb).cleaner();
+- if (cl != null)
+- cl.clean();
++ if (invokeCleaner != null) {
++ try {
++ invokeCleaner.invoke(unsafe, bb);
++ } catch (Throwable e) {
++
++ }
++ }
+ }
+ }
+ }
+--- a/lang/src/main/java/net/openhft/lang/io/NativeBytes.java
++++ b/lang/src/main/java/net/openhft/lang/io/NativeBytes.java
+@@ -21,6 +21,10 @@
+ import org.jetbrains.annotations.NotNull;
+ import sun.misc.Unsafe;
+
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++
+ import java.io.EOFException;
+ import java.io.IOException;
+ import java.lang.reflect.Field;
+@@ -41,6 +45,7 @@
+ @NotNull
+ @SuppressWarnings("ALL")
+ public static final Unsafe UNSAFE;
++ public static final MethodHandle defineClassMethodHandle;
+ protected static final long NO_PAGE;
+ static final int BYTES_OFFSET;
+ static final int CHARS_OFFSET;
+@@ -57,6 +62,14 @@
+ throw new AssertionError(e);
+ }
+ NO_PAGE = UNSAFE.allocateMemory(UNSAFE.pageSize());
++ try {
++ MethodHandles.Lookup baseLookup = MethodHandles.lookup();
++ MethodType defineClassMethodType = MethodType.methodType(Class.class, new Class[]{String.class, byte[].class, int.class, int.class});
++ MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(ClassLoader.class, baseLookup);
++ defineClassMethodHandle = lookup.findVirtual(ClassLoader.class, "defineClass", defineClassMethodType);
++ } catch (Throwable e) {
++ throw new RuntimeException(e);
++ }
+ }
+
+ protected long startAddr;
+--- a/lang/src/main/java/net/openhft/lang/io/VanillaMappedBytes.java
++++ b/lang/src/main/java/net/openhft/lang/io/VanillaMappedBytes.java
+@@ -15,7 +15,6 @@
+ */
+ package net.openhft.lang.io;
+
+-import sun.misc.Cleaner;
+ import sun.nio.ch.DirectBuffer;
+
+ import java.io.File;
+@@ -23,6 +22,7 @@
+ import java.nio.ByteBuffer;
+ import java.nio.MappedByteBuffer;
+ import java.nio.channels.FileChannel;
++import java.lang.reflect.Method;
+
+ public class VanillaMappedBytes extends NativeBytes {
+ private final File path;
+@@ -31,6 +31,18 @@
+ private final FileLifecycleListener fileLifecycleListener;
+ private final long index;
+ private boolean unmapped;
++ private static final Method invokeCleaner;
++
++ static {
++ Method tmpCleaner;
++ try {
++ tmpCleaner = UNSAFE.getClass().getDeclaredMethod("invokeCleaner", ByteBuffer.class);
++ tmpCleaner.setAccessible(true);
++ } catch (Throwable t) {
++ tmpCleaner = null;
++ }
++ invokeCleaner = tmpCleaner;
++ }
+
+ public VanillaMappedBytes(final File path, final MappedByteBuffer buffer) {
+ this(path, buffer, -1, null, FileLifecycleListener.FileLifecycleListeners.IGNORE);
+@@ -92,10 +104,13 @@
+ @Override
+ protected synchronized void cleanup() {
+ if(!this.unmapped) {
+- Cleaner cl = ((DirectBuffer)this.buffer).cleaner();
+- if (cl != null) {
++ if (invokeCleaner != null) {
+ long start = System.nanoTime();
+- cl.clean();
++ try {
++ invokeCleaner.invoke(UNSAFE, this.buffer);
++ } catch (Throwable e) {
++
++ }
+
+ fileLifecycleListener.onEvent(
+ FileLifecycleListener.EventType.UNMAP,