ignite-6743 DirectBuffer and DirectByteBuffer usages are removed

Signed-off-by: Andrey Gura <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/5fb4c136
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/5fb4c136
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/5fb4c136

Branch: refs/heads/ignite-zk
Commit: 5fb4c136e619ee48c9c23cf89951095db04e7ed0
Parents: 264ba07
Author: Andrey Kuznetsov <[email protected]>
Authored: Tue Dec 26 15:20:50 2017 +0300
Committer: Andrey Gura <[email protected]>
Committed: Tue Dec 26 15:26:28 2017 +0300

----------------------------------------------------------------------
 .../wal/SegmentedRingByteBuffer.java            |  4 +-
 .../internal/util/DirectBufferCleaner.java      | 32 ++++++++++
 .../apache/ignite/internal/util/GridUnsafe.java | 39 +++++++++++-
 .../util/ReflectiveDirectBufferCleaner.java     | 64 ++++++++++++++++++++
 .../util/UnsafeDirectBufferCleaner.java         | 47 ++++++++++++++
 .../ignite/internal/util/nio/GridNioServer.java |  6 +-
 6 files changed, 185 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5fb4c136/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/SegmentedRingByteBuffer.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/SegmentedRingByteBuffer.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/SegmentedRingByteBuffer.java
index a0209f9..43fe71a 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/SegmentedRingByteBuffer.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/SegmentedRingByteBuffer.java
@@ -26,8 +26,8 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import java.util.concurrent.atomic.AtomicLongFieldUpdater;
 import 
org.apache.ignite.internal.processors.cache.persistence.DataStorageMetricsImpl;
+import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.typedef.internal.S;
-import sun.nio.ch.DirectBuffer;
 
 import static java.nio.ByteBuffer.allocate;
 import static java.nio.ByteBuffer.allocateDirect;
@@ -376,7 +376,7 @@ public class SegmentedRingByteBuffer {
      */
     public void free() {
         if (mode == DIRECT || mode == MAPPED)
-            ((DirectBuffer)buf).cleaner().clean();
+            GridUnsafe.cleanDirectBuffer(buf);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/5fb4c136/modules/core/src/main/java/org/apache/ignite/internal/util/DirectBufferCleaner.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/DirectBufferCleaner.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/util/DirectBufferCleaner.java
new file mode 100644
index 0000000..2608d8a
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/util/DirectBufferCleaner.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.util;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Cleaner interface for {@code java.nio.ByteBuffer}.
+ */
+public interface DirectBufferCleaner {
+    /**
+     * Cleans direct buffer.
+     *
+     * @param buf direct buffer.
+     */
+    public void clean(ByteBuffer buf);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5fb4c136/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java 
b/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java
index 55ff421..c4583a2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.internal.util;
 
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -29,7 +31,8 @@ import org.apache.ignite.IgniteSystemProperties;
 import sun.misc.JavaNioAccess;
 import sun.misc.SharedSecrets;
 import sun.misc.Unsafe;
-import sun.nio.ch.DirectBuffer;
+
+import static org.apache.ignite.internal.util.IgniteUtils.majorJavaVersion;
 
 /**
  * <p>Wrapper for {@link sun.misc.Unsafe} class.</p>
@@ -102,6 +105,12 @@ public abstract class GridUnsafe {
     /** {@link java.nio.Buffer#address} field offset. */
     private static final long DIRECT_BUF_ADDR_OFF = bufferAddressOffset();
 
+    /** Cleaner code for direct {@code java.nio.ByteBuffer}. */
+    private static final DirectBufferCleaner DIRECT_BUF_CLEANER =
+        majorJavaVersion(System.getProperty("java.specification.version")) < 9
+            ? new ReflectiveDirectBufferCleaner()
+            : new UnsafeDirectBufferCleaner();
+
     /**
      * Ensure singleton.
      */
@@ -117,7 +126,7 @@ public abstract class GridUnsafe {
     public static ByteBuffer wrapPointer(long ptr, int len) {
         ByteBuffer buf = nioAccess.newDirectByteBuffer(ptr, len, null);
 
-        assert buf instanceof DirectBuffer;
+        assert buf.isDirect();
 
         buf.order(NATIVE_BYTE_ORDER);
 
@@ -1344,6 +1353,32 @@ public abstract class GridUnsafe {
     }
 
     /**
+     * Invokes some method on {@code sun.misc.Unsafe} instance.
+     *
+     * @param mtd Method.
+     * @param args Arguments.
+     */
+    public static Object invoke(Method mtd, Object... args) {
+        try {
+            return mtd.invoke(UNSAFE, args);
+        }
+        catch (IllegalAccessException | InvocationTargetException e) {
+            throw new RuntimeException("Unsafe invocation failed [cls=" + 
UNSAFE.getClass() + ", mtd=" + mtd + ']', e);
+        }
+    }
+
+    /**
+     * Cleans direct {@code java.nio.ByteBuffer}
+     *
+     * @param buf Direct buffer.
+     */
+    public static void cleanDirectBuffer(ByteBuffer buf) {
+        assert buf.isDirect();
+
+        DIRECT_BUF_CLEANER.clean(buf);
+    }
+
+    /**
      * Returns unaligned flag.
      */
     private static boolean unaligned() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/5fb4c136/modules/core/src/main/java/org/apache/ignite/internal/util/ReflectiveDirectBufferCleaner.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/ReflectiveDirectBufferCleaner.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/util/ReflectiveDirectBufferCleaner.java
new file mode 100644
index 0000000..00ac787
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/util/ReflectiveDirectBufferCleaner.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
+/**
+ * {@link DirectBufferCleaner} implementation based on {@code 
sun.misc.Cleaner} and
+ * {@code sun.nio.ch.DirectBuffer.cleaner()} method.
+ *
+ * Mote: This implementation will not work on Java 9+.
+ */
+public class ReflectiveDirectBufferCleaner implements DirectBufferCleaner {
+    /** Cleaner method. */
+    private final Method cleanerMtd;
+
+    /** Clean method. */
+    private final Method cleanMtd;
+
+    /** */
+    public ReflectiveDirectBufferCleaner() {
+        try {
+            cleanerMtd = 
Class.forName("sun.nio.ch.DirectBuffer").getMethod("cleaner");
+
+        }
+        catch (ClassNotFoundException | NoSuchMethodException e) {
+            throw new RuntimeException("No sun.nio.ch.DirectBuffer.cleaner() 
method found", e);
+        }
+
+        try {
+            cleanMtd = Class.forName("sun.misc.Cleaner").getMethod("clean");
+        }
+        catch (ClassNotFoundException | NoSuchMethodException e) {
+            throw new RuntimeException("No sun.misc.Cleaner.clean() method 
found", e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clean(ByteBuffer buf) {
+        try {
+            cleanMtd.invoke(cleanerMtd.invoke(buf));
+        }
+        catch (IllegalAccessException | InvocationTargetException e) {
+            throw new RuntimeException("Failed to invoke direct buffer 
cleaner", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5fb4c136/modules/core/src/main/java/org/apache/ignite/internal/util/UnsafeDirectBufferCleaner.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/UnsafeDirectBufferCleaner.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/util/UnsafeDirectBufferCleaner.java
new file mode 100644
index 0000000..547f092
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/util/UnsafeDirectBufferCleaner.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.util;
+
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import sun.misc.Unsafe;
+
+/**
+ * {@link DirectBufferCleaner} implementation based on {@code 
Unsafe.invokeCleaner} method.
+ *
+ * Note: This implementation will work only for Java 9+.
+ */
+public class UnsafeDirectBufferCleaner implements DirectBufferCleaner {
+    /** Cleaner method. */
+    private final Method cleanerMtd;
+
+    /** */
+    public UnsafeDirectBufferCleaner() {
+        try {
+            cleanerMtd = Unsafe.class.getMethod("invokeCleaner", 
ByteBuffer.class);
+        }
+        catch (NoSuchMethodException e) {
+            throw new RuntimeException("Reflection failure: no 
sun.misc.Unsafe.invokeCleaner() method found", e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clean(ByteBuffer buf) {
+        GridUnsafe.invoke(cleanerMtd, buf);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5fb4c136/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
index 97f6020..3a88507 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
@@ -56,6 +56,7 @@ import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 import org.apache.ignite.internal.managers.communication.GridIoMessage;
 import org.apache.ignite.internal.util.GridConcurrentHashSet;
+import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.nio.ssl.GridNioSslFilter;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -75,7 +76,6 @@ import 
org.apache.ignite.plugin.extensions.communication.MessageReader;
 import org.apache.ignite.plugin.extensions.communication.MessageWriter;
 import org.apache.ignite.thread.IgniteThread;
 import org.jetbrains.annotations.Nullable;
-import sun.nio.ch.DirectBuffer;
 
 import static 
org.apache.ignite.internal.util.nio.GridNioSessionMetaKey.MSG_WRITER;
 import static 
org.apache.ignite.internal.util.nio.GridNioSessionMetaKey.NIO_OPERATION;
@@ -2573,10 +2573,10 @@ public class GridNioServer<T> {
 
                 if (directBuf) {
                     if (ses.writeBuffer() != null)
-                        ((DirectBuffer)ses.writeBuffer()).cleaner().clean();
+                        GridUnsafe.cleanDirectBuffer(ses.writeBuffer());
 
                     if (ses.readBuffer() != null)
-                        ((DirectBuffer)ses.readBuffer()).cleaner().clean();
+                        GridUnsafe.cleanDirectBuffer(ses.readBuffer());
                 }
 
                 closeKey(ses.key());

Reply via email to