From f5ce78257bafc41546bbd653d3c4bbf85a070778 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 04 Mar 2016 17:02:46 +0000
Subject: [PATCH] OPENDJ-2743 Delay run-time linking of Unsafe until we are sure that it is available

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java     |   61 ++++++++++++++----------------
 opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java |   14 +++++-
 2 files changed, 39 insertions(+), 36 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
index 351a89d..a4f69ca 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
@@ -28,7 +28,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.lang.reflect.Field;
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
@@ -466,7 +465,7 @@
 
     private int computeBufferSize(int nbBuffer) throws InitializationException
     {
-      if (BufferPool.supportOffHeap())
+      if (BufferPool.SUPPORTS_OFF_HEAP)
       {
         return MAX_BUFFER_SIZE;
       }
@@ -2719,30 +2718,23 @@
    */
   static final class BufferPool implements Closeable
   {
-    private final BlockingQueue<Buffer> pool;
-    private final int bufferSize;
-
-    private static final Unsafe unsafe;
-    private static final long BYTE_ARRAY_OFFSET;
+    static final boolean SUPPORTS_OFF_HEAP;
     static
     {
-        try
-        {
-            Field field = Unsafe.class.getDeclaredField("theUnsafe");
-            field.setAccessible(true);
-            unsafe = (Unsafe)field.get(null);
-            BYTE_ARRAY_OFFSET = unsafe.arrayBaseOffset(byte[].class);
-        }
-        catch (Exception e)
-        {
-            throw new RuntimeException(e);
-        }
+      boolean isUnsafeSupported = false;
+      try
+      {
+        isUnsafeSupported = Class.forName("sun.misc.Unsafe") != null;
+      }
+      catch (Throwable e)
+      {
+        // Unsupported.
+      }
+      SUPPORTS_OFF_HEAP = isUnsafeSupported;
     }
 
-    private static boolean supportOffHeap()
-    {
-      return unsafe != null;
-    }
+    private final BlockingQueue<Buffer> pool;
+    private final int bufferSize;
 
     BufferPool(int nbBuffer, int bufferSize)
     {
@@ -2750,7 +2742,7 @@
       this.bufferSize = bufferSize;
       for (int i = 0; i < nbBuffer; i++)
       {
-        pool.offer(supportOffHeap() ? new OffHeapBuffer(bufferSize) : new HeapBuffer(bufferSize));
+        pool.offer(SUPPORTS_OFF_HEAP ? new OffHeapBuffer(bufferSize) : new HeapBuffer(bufferSize));
       }
     }
 
@@ -2804,6 +2796,9 @@
     /** Off-heap buffer using Unsafe memory access. */
     static final class OffHeapBuffer implements Buffer
     {
+      private static final Unsafe UNSAFE = Unsafe.getUnsafe();
+      private static final long BYTE_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
+
       private final long address;
       private final int size;
       private int position;
@@ -2812,7 +2807,7 @@
         @Override
         public int read() throws IOException
         {
-          return unsafe.getByte(address + position++) & 0xFF;
+          return UNSAFE.getByte(address + position++) & 0xFF;
         }
       };
       private final OutputStream asOutputStream = new OutputStream()
@@ -2820,7 +2815,7 @@
         @Override
         public void write(int value) throws IOException
         {
-          unsafe.putByte(address + position++, (byte) (value & 0xFF));
+          UNSAFE.putByte(address + position++, (byte) (value & 0xFF));
         }
       };
       private boolean closed;
@@ -2828,19 +2823,19 @@
       OffHeapBuffer(int size)
       {
         this.size = size;
-        this.address = unsafe.allocateMemory(size);
+        this.address = UNSAFE.allocateMemory(size);
       }
 
       @Override
       public void writeInt(final int position, final int value)
       {
-        unsafe.putInt(address + position, value);
+        UNSAFE.putInt(address + position, value);
       }
 
       @Override
       public int readInt(final int position)
       {
-        return unsafe.getInt(address + position);
+        return UNSAFE.getInt(address + position);
       }
 
       @Override
@@ -2879,7 +2874,7 @@
         long offset = address + position;
         for(int i = 0 ; i < data.length() ; i++)
         {
-          unsafe.putByte(offset++, data.byteAt(i));
+          UNSAFE.putByte(offset++, data.byteAt(i));
         }
       }
 
@@ -2895,7 +2890,7 @@
         Reject.ifFalse(position + length <= size);
 
         final byte[] data = new byte[length];
-        unsafe.copyMemory(null, address + position, data, BYTE_ARRAY_OFFSET, length);
+        UNSAFE.copyMemory(null, address + position, data, BYTE_ARRAY_OFFSET, length);
         return ByteString.wrap(data);
       }
 
@@ -2905,8 +2900,8 @@
         final int len = Math.min(lengthA, lengthB);
         for(int i = 0 ; i < len ; i++)
         {
-          final int a = unsafe.getByte(address + offsetA + i) & 0xFF;
-          final int b = unsafe.getByte(address + offsetB + i) & 0xFF;
+          final int a = UNSAFE.getByte(address + offsetA + i) & 0xFF;
+          final int b = UNSAFE.getByte(address + offsetB + i) & 0xFF;
           if ( a != b )
           {
             return a - b;
@@ -2920,7 +2915,7 @@
       {
         if (!closed)
         {
-          unsafe.freeMemory(address);
+          UNSAFE.freeMemory(address);
         }
         closed = true;
       }
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java
index 59a6579..dd694f8 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java
@@ -66,15 +66,23 @@
 public class OnDiskMergeImporterTest extends DirectoryServerTestCase
 {
   @Test
-  public void testBuffer() throws IOException
+  public void testHeapBuffer() throws IOException
   {
     try(Buffer buffer = new HeapBuffer(1024))
     {
       testBufferImplementation(buffer);
     }
-    try (Buffer buffer = new OffHeapBuffer(1024))
+  }
+
+  @Test
+  public void testOffHeapBuffer() throws IOException
+  {
+    if (BufferPool.SUPPORTS_OFF_HEAP)
     {
-      testBufferImplementation(buffer);
+      try (Buffer buffer = new OffHeapBuffer(1024))
+      {
+        testBufferImplementation(buffer);
+      }
     }
   }
 

--
Gitblit v1.10.0