You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by an...@apache.org on 2015/07/30 11:14:23 UTC

[1/9] activemq-artemis git commit: ARTEMIS-163 First pass on the native AIO refactoring

Repository: activemq-artemis
Updated Branches:
  refs/heads/master 661f695ee -> 8182f8bd2


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AsynchronousFileTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AsynchronousFileTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AsynchronousFileTest.java
deleted file mode 100644
index 434dcc8..0000000
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AsynchronousFileTest.java
+++ /dev/null
@@ -1,1015 +0,0 @@
-/*
- * 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.activemq.artemis.tests.unit.core.asyncio;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
-import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-/**
- * you need to define -Djava.library.path=${project-root}/native/src/.libs when calling the JVM
- * If you are running this test in eclipse you should do:
- * I - Run->Open Run Dialog
- * II - Find the class on the list (you will find it if you already tried running this testcase before)
- * III - Add -Djava.library.path=<your project place>/native/src/.libs
- */
-public class AsynchronousFileTest extends AIOTestBase
-{
-
-   @BeforeClass
-   public static void hasAIO()
-   {
-      org.junit.Assume.assumeTrue("Test case needs AIO to run", AIOSequentialFileFactory.isSupported());
-   }
-
-   private static CharsetEncoder UTF_8_ENCODER = StandardCharsets.UTF_8.newEncoder();
-
-   byte[] commonBuffer = null;
-
-   ExecutorService executor;
-
-   ExecutorService pollerExecutor;
-
-   private AsynchronousFileImpl controller;
-   private ByteBuffer buffer;
-
-   private final BufferCallback bufferCallbackDestroy = new BufferCallback()
-   {
-
-      public void bufferDone(final ByteBuffer buffer1)
-      {
-         AsynchronousFileImpl.destroyBuffer(buffer1);
-      }
-
-   };
-
-   private static void debug(final String msg)
-   {
-      UnitTestLogger.LOGGER.debug(msg);
-   }
-
-   @Override
-   @Before
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      pollerExecutor = Executors.newCachedThreadPool(new ActiveMQThreadFactory("ActiveMQ-AIO-poller-pool" + System.identityHashCode(this),
-                                                                              false,
-                                                                              this.getClass().getClassLoader()));
-      executor = Executors.newSingleThreadExecutor();
-   }
-
-   @Override
-   @After
-   public void tearDown() throws Exception
-   {
-      destroy(buffer);
-      if (controller != null)
-      {
-         try
-         {
-            controller.close();
-         }
-         catch (Exception e)
-         {
-            // ignored
-         }
-      }
-      executor.shutdown();
-      pollerExecutor.shutdown();
-      super.tearDown();
-   }
-
-   /**
-    * Opening and closing a file immediately can lead to races on the native layer,
-    * creating crash conditions.
-    */
-   @Test
-   public void testOpenClose() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      for (int i = 0; i < 100; i++)
-      {
-         controller.open(fileName, 10000);
-         controller.close();
-
-      }
-   }
-
-   @Test
-   public void testReleaseBuffers() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      WeakReference<ByteBuffer> bufferCheck = null;
-
-      controller.open(fileName, 10000);
-      bufferCheck = new WeakReference<ByteBuffer>(controller.getHandler());
-      controller.fill(0, 10, 1024, (byte) 0);
-
-      ByteBuffer write = AsynchronousFileImpl.newBuffer(1024);
-
-      for (int i = 0; i < 1024; i++)
-      {
-         write.put(ActiveMQTestBase.getSamplebyte(i));
-      }
-
-      final CountDownLatch latch = new CountDownLatch(1);
-
-      controller.write(0, 1024, write, new AIOCallback()
-      {
-
-         public void onError(final int errorCode, final String errorMessage)
-         {
-         }
-
-         public void done()
-         {
-            latch.countDown();
-         }
-      });
-
-      assertTrue(latch.await(10, TimeUnit.SECONDS));
-
-      WeakReference<ByteBuffer> bufferCheck2 = new WeakReference<ByteBuffer>(write);
-
-      destroy(write);
-
-      write = null;
-
-      ActiveMQTestBase.forceGC(bufferCheck2, 5000);
-
-      assertNull(bufferCheck2.get());
-
-      controller.close();
-
-      controller = null;
-
-      ActiveMQTestBase.forceGC(bufferCheck, 5000);
-
-      assertNull(bufferCheck.get());
-   }
-
-   @Test
-   public void testFileNonExistent() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      for (int i = 0; i < 100; i++)
-      {
-         try
-         {
-            controller.open("/non-existent/IDontExist.error", 10000);
-            fail("Exception expected! The test could create a file called /non-existent/IDontExist.error when it was supposed to fail.");
-         }
-         catch (Exception ignored)
-         {
-         }
-         try
-         {
-            controller.close();
-            fail("Supposed to throw exception as the file wasn't opened");
-         }
-         catch (Exception ignored)
-         {
-         }
-
-      }
-   }
-
-   /**
-    * This test is validating if the AIO layer can open two different
-    * simultaneous files without loose any callbacks. This test made the native
-    * layer to crash at some point during development
-    */
-   @Test
-   public void testTwoFiles() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      final AsynchronousFileImpl controller2 = new AsynchronousFileImpl(executor, pollerExecutor);
-      controller.open(fileName + ".1", 10000);
-      controller2.open(fileName + ".2", 10000);
-
-      int numberOfLines = 1000;
-      int size = 1024;
-
-      ArrayList<Integer> listResult1 = new ArrayList<Integer>();
-      ArrayList<Integer> listResult2 = new ArrayList<Integer>();
-
-      AtomicInteger errors = new AtomicInteger(0);
-
-
-      try
-      {
-         CountDownLatch latchDone = new CountDownLatch(numberOfLines);
-         CountDownLatch latchDone2 = new CountDownLatch(numberOfLines);
-
-         buffer = AsynchronousFileImpl.newBuffer(size);
-         encodeBufer(buffer);
-
-         preAlloc(controller, numberOfLines * size);
-         preAlloc(controller2, numberOfLines * size);
-
-         ArrayList<CountDownCallback> list = new ArrayList<CountDownCallback>();
-         ArrayList<CountDownCallback> list2 = new ArrayList<CountDownCallback>();
-
-         for (int i = 0; i < numberOfLines; i++)
-         {
-            list.add(new CountDownCallback(latchDone, errors, listResult1, i));
-            list2.add(new CountDownCallback(latchDone2, errors, listResult2, i));
-         }
-
-         int counter = 0;
-
-         Iterator<CountDownCallback> iter2 = list2.iterator();
-
-         for (CountDownCallback cb1 : list)
-         {
-            CountDownCallback cb2 = iter2.next();
-
-            controller.write(counter * size, size, buffer, cb1);
-            controller2.write(counter * size, size, buffer, cb2);
-            ++counter;
-
-         }
-
-         ActiveMQTestBase.waitForLatch(latchDone);
-         ActiveMQTestBase.waitForLatch(latchDone2);
-
-         CountDownCallback.checkResults(numberOfLines, listResult1);
-         CountDownCallback.checkResults(numberOfLines, listResult2);
-
-         for (CountDownCallback callback : list)
-         {
-            assertEquals(1, callback.timesDoneCalled.get());
-            assertTrue(callback.doneCalled);
-         }
-
-         for (CountDownCallback callback : list2)
-         {
-            assertEquals(1, callback.timesDoneCalled.get());
-            assertTrue(callback.doneCalled);
-         }
-
-         assertEquals(0, errors.get());
-
-         controller.close();
-      }
-      finally
-      {
-         try
-         {
-            controller2.close();
-         }
-         catch (Exception ignored)
-         {
-         }
-      }
-   }
-
-   @Test
-   public void testAddBeyongSimultaneousLimit() throws Exception
-   {
-      asyncData(3000, 1024, 10);
-   }
-
-   @Test
-   public void testAddAsyncData() throws Exception
-   {
-      asyncData(10000, 1024, 30000);
-   }
-
-   private static final class LocalCallback implements AIOCallback
-   {
-      private final CountDownLatch latch = new CountDownLatch(1);
-
-      volatile boolean error;
-
-      public void done()
-      {
-         latch.countDown();
-      }
-
-      public void onError(final int errorCode, final String errorMessage)
-      {
-         error = true;
-         latch.countDown();
-      }
-   }
-
-   @Test
-   public void testReleaseNullBuffer() throws Exception
-   {
-      boolean failed = false;
-      try
-      {
-         AsynchronousFileImpl.destroyBuffer(null);
-      }
-      catch (Exception expected)
-      {
-         failed = true;
-      }
-
-      assertTrue("Exception expected", failed);
-   }
-
-   @Test
-   public void testInvalidReads() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-
-      final int SIZE = 512;
-
-      controller.open(fileName, 10);
-      controller.close();
-
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-
-      controller.open(fileName, 10);
-
-      controller.fill(0, 1, 512, (byte) 'j');
-
-      buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
-      buffer.clear();
-
-      for (int i = 0; i < SIZE; i++)
-      {
-         buffer.put((byte) (i % 100));
-      }
-
-      LocalCallback callbackLocal = new LocalCallback();
-
-      controller.write(0, 512, buffer, callbackLocal);
-
-      waitForLatch(callbackLocal.latch);
-
-      {
-         ByteBuffer newBuffer = AsynchronousFileImpl.newBuffer(512);
-
-         try
-         {
-            callbackLocal = new LocalCallback();
-
-            controller.read(0, 50, newBuffer, callbackLocal);
-
-            waitForLatch(callbackLocal.latch);
-
-            assertTrue(callbackLocal.error);
-
-         }
-         finally
-         {
-            // We have to destroy the native buffer manually as it was created with a malloc like C function
-            destroy(newBuffer);
-            newBuffer = null;
-         }
-      }
-      callbackLocal = new LocalCallback();
-
-      byte[] bytes = new byte[512];
-
-      {
-         try
-         {
-            ByteBuffer newBuffer = ByteBuffer.wrap(bytes);
-
-            controller.read(0, 512, newBuffer, callbackLocal);
-
-            fail("An exception was supposed to be thrown");
-         }
-         catch (ActiveMQException ignored)
-         {
-            System.out.println(ignored);
-         }
-      }
-
-      {
-         final ByteBuffer newBuffer = AsynchronousFileImpl.newBuffer(512);
-         try
-         {
-            callbackLocal = new LocalCallback();
-            controller.read(0, 512, newBuffer, callbackLocal);
-            waitForLatch(callbackLocal.latch);
-            assertFalse(callbackLocal.error);
-
-            newBuffer.rewind();
-
-            byte[] bytesRead = new byte[SIZE];
-
-            newBuffer.get(bytesRead);
-
-            for (int i = 0; i < SIZE; i++)
-            {
-               assertEquals((byte) (i % 100), bytesRead[i]);
-            }
-         }
-         finally
-         {
-            destroy(newBuffer);
-         }
-      }
-   }
-
-   private static void destroy(ByteBuffer buffer0)
-   {
-      if (buffer0 != null)
-      {
-         AsynchronousFileImpl.destroyBuffer(buffer0);
-      }
-   }
-
-   @Test
-   public void testBufferCallbackUniqueBuffers() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      final int NUMBER_LINES = 1000;
-      final int SIZE = 512;
-
-      controller.open(fileName, 1000);
-
-      controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
-      final ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
-
-      BufferCallback bufferCallback = new BufferCallback()
-      {
-         public void bufferDone(final ByteBuffer buffer)
-         {
-            buffers.add(buffer);
-         }
-      };
-
-      controller.setBufferCallback(bufferCallback);
-
-      CountDownLatch latch = new CountDownLatch(NUMBER_LINES);
-      ArrayList<Integer> result = new ArrayList<Integer>();
-      for (int i = 0; i < NUMBER_LINES; i++)
-      {
-         ByteBuffer buffer1 = AsynchronousFileImpl.newBuffer(SIZE);
-         buffer1.rewind();
-         for (int j = 0; j < SIZE; j++)
-         {
-            buffer1.put((byte) (j % Byte.MAX_VALUE));
-         }
-         CountDownCallback aio = new CountDownCallback(latch, null, result, i);
-         controller.write(i * SIZE, SIZE, buffer1, aio);
-      }
-
-      // The buffer callback is only called after the complete callback was
-      // called.
-      // Because of that a race could happen on the assertions to
-      // buffers.size what would invalidate the test
-      // We close the file and that would guarantee the buffer callback was
-      // called for all the elements
-      controller.close();
-
-      CountDownCallback.checkResults(NUMBER_LINES, result);
-
-      // Make sure all the buffers are unique
-      ByteBuffer lineOne = null;
-      for (ByteBuffer bufferTmp : buffers)
-      {
-         if (lineOne == null)
-         {
-            lineOne = bufferTmp;
-         }
-         else
-         {
-            assertTrue(lineOne != bufferTmp);
-         }
-      }
-
-      for (ByteBuffer bufferTmp : buffers)
-      {
-         destroy(bufferTmp);
-      }
-
-      buffers.clear();
-   }
-
-   @Test
-   public void testBufferCallbackAwaysSameBuffer() throws Exception
-   {
-
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-
-      final int NUMBER_LINES = 1000;
-      final int SIZE = 512;
-
-      controller.open(fileName, 1000);
-
-      controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
-      final ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
-
-      BufferCallback bufferCallback = new BufferCallback()
-      {
-         public void bufferDone(final ByteBuffer buffer)
-         {
-            buffers.add(buffer);
-         }
-      };
-
-      controller.setBufferCallback(bufferCallback);
-
-      CountDownLatch latch = new CountDownLatch(NUMBER_LINES);
-
-      buffer = AsynchronousFileImpl.newBuffer(SIZE);
-      buffer.rewind();
-      for (int j = 0; j < SIZE; j++)
-      {
-         buffer.put((byte) (j % Byte.MAX_VALUE));
-      }
-
-      ArrayList<Integer> result = new ArrayList<Integer>();
-
-      for (int i = 0; i < NUMBER_LINES; i++)
-      {
-         CountDownCallback aio = new CountDownCallback(latch, null, result, i);
-         controller.write(i * SIZE, SIZE, buffer, aio);
-      }
-
-      // The buffer callback is only called after the complete callback was
-      // called.
-      // Because of that a race could happen on the assertions to
-      // buffers.size what would invalidate the test
-      // We close the file and that would guarantee the buffer callback was
-      // called for all the elements
-      controller.close();
-
-      CountDownCallback.checkResults(NUMBER_LINES, result);
-
-      assertEquals(NUMBER_LINES, buffers.size());
-
-      // Make sure all the buffers are unique
-      ByteBuffer lineOne = null;
-      for (ByteBuffer bufferTmp : buffers)
-      {
-         if (lineOne == null)
-         {
-            lineOne = bufferTmp;
-         }
-         else
-         {
-            assertTrue(lineOne == bufferTmp);
-         }
-      }
-
-      buffers.clear();
-   }
-
-   @Test
-   public void testRead() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      controller.setBufferCallback(bufferCallbackDestroy);
-
-      final int NUMBER_LINES = 1000;
-      final int SIZE = 1024;
-
-      controller.open(fileName, 1000);
-
-      controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
-      {
-         CountDownLatch latch = new CountDownLatch(NUMBER_LINES);
-         ArrayList<Integer> result = new ArrayList<Integer>();
-
-         AtomicInteger errors = new AtomicInteger(0);
-
-         for (int i = 0; i < NUMBER_LINES; i++)
-         {
-            if (i % 100 == 0)
-            {
-               System.out.println("Wrote " + i + " lines");
-            }
-            final ByteBuffer buffer0 = AsynchronousFileImpl.newBuffer(SIZE);
-            for (int j = 0; j < SIZE; j++)
-            {
-               buffer0.put(ActiveMQTestBase.getSamplebyte(j));
-            }
-
-            CountDownCallback aio = new CountDownCallback(latch, errors, result, i);
-            controller.write(i * SIZE, SIZE, buffer0, aio);
-         }
-
-         waitForLatch(latch);
-
-         assertEquals(0, errors.get());
-
-         CountDownCallback.checkResults(NUMBER_LINES, result);
-      }
-
-      // If you call close you're supposed to wait events to finish before
-      // closing it
-      controller.close();
-      controller.setBufferCallback(null);
-
-      controller.open(fileName, 10);
-
-      buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
-      for (int i = 0; i < NUMBER_LINES; i++)
-      {
-         if (i % 100 == 0)
-         {
-            System.out.println("Read " + i + " lines");
-         }
-         AsynchronousFileImpl.clearBuffer(buffer);
-
-         CountDownLatch latch = new CountDownLatch(1);
-         AtomicInteger errors = new AtomicInteger(0);
-         CountDownCallback aio = new CountDownCallback(latch, errors, null, 0);
-
-         controller.read(i * SIZE, SIZE, buffer, aio);
-
-         waitForLatch(latch);
-         assertEquals(0, errors.get());
-         assertTrue(aio.doneCalled);
-
-         byte[] bytesRead = new byte[SIZE];
-         buffer.get(bytesRead);
-
-         for (int count = 0; count < SIZE; count++)
-         {
-            Assert.assertEquals("byte position " + count + " differs on line " + i + " position = " + count,
-                                ActiveMQTestBase.getSamplebyte(count),
-                                bytesRead[count]);
-         }
-      }
-   }
-
-   /**
-    * This test will call file.close() when there are still callbacks being processed.
-    * This could cause a crash or callbacks missing and this test is validating both situations.
-    * The file is also read after being written to validate its correctness
-    */
-   @Test
-   public void testConcurrentClose() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      final int NUMBER_LINES = 1000;
-      CountDownLatch readLatch = new CountDownLatch(NUMBER_LINES);
-      final int SIZE = 1024;
-
-      controller.open(fileName, 10000);
-
-      controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
-      controller.setBufferCallback(bufferCallbackDestroy);
-
-      for (int i = 0; i < NUMBER_LINES; i++)
-      {
-         ByteBuffer buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
-         buffer.clear();
-         addString("Str value " + i + "\n", buffer);
-         for (int j = buffer.position(); j < buffer.capacity() - 1; j++)
-         {
-            buffer.put((byte) ' ');
-         }
-         buffer.put((byte) '\n');
-
-         CountDownCallback aio = new CountDownCallback(readLatch, null, null, 0);
-         controller.write(i * SIZE, SIZE, buffer, aio);
-      }
-
-      // If you call close you're supposed to wait events to finish before
-      // closing it
-      controller.close();
-
-      controller.setBufferCallback(null);
-
-      assertEquals(0, readLatch.getCount());
-      waitForLatch(readLatch);
-      controller.open(fileName, 10);
-
-      ByteBuffer newBuffer = AsynchronousFileImpl.newBuffer(SIZE);
-
-      ByteBuffer buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
-      for (int i = 0; i < NUMBER_LINES; i++)
-      {
-         newBuffer.clear();
-         addString("Str value " + i + "\n", newBuffer);
-         for (int j = newBuffer.position(); j < newBuffer.capacity() - 1; j++)
-         {
-            newBuffer.put((byte) ' ');
-         }
-         newBuffer.put((byte) '\n');
-
-         CountDownLatch latch = new CountDownLatch(1);
-         CountDownCallback aio = new CountDownCallback(latch, null, null, 0);
-         controller.read(i * SIZE, SIZE, buffer, aio);
-         waitForLatch(latch);
-         assertEquals(0, aio.errorCalled);
-         assertTrue(aio.doneCalled);
-
-         byte[] bytesRead = new byte[SIZE];
-         byte[] bytesCompare = new byte[SIZE];
-
-         newBuffer.rewind();
-         newBuffer.get(bytesCompare);
-         buffer.rewind();
-         buffer.get(bytesRead);
-
-         for (int count = 0; count < SIZE; count++)
-         {
-            assertEquals("byte position " + count + " differs on line " + i,
-                                bytesCompare[count],
-                                bytesRead[count]);
-         }
-
-         assertTrue(buffer.equals(newBuffer));
-      }
-
-      destroy(newBuffer);
-   }
-
-   private void asyncData(final int numberOfLines, final int size, final int aioLimit) throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      controller.open(fileName, aioLimit);
-
-
-      CountDownLatch latchDone = new CountDownLatch(numberOfLines);
-
-      buffer = AsynchronousFileImpl.newBuffer(size);
-      encodeBufer(buffer);
-
-      preAlloc(controller, numberOfLines * size);
-
-      ArrayList<CountDownCallback> list = new ArrayList<CountDownCallback>();
-
-      ArrayList<Integer> result = new ArrayList<Integer>();
-
-      for (int i = 0; i < numberOfLines; i++)
-      {
-         list.add(new CountDownCallback(latchDone, null, result, i));
-      }
-
-      long valueInitial = System.currentTimeMillis();
-
-      long lastTime = System.currentTimeMillis();
-      int counter = 0;
-      for (CountDownCallback tmp : list)
-      {
-         controller.write(counter * size, size, buffer, tmp);
-         if (++counter % 20000 == 0)
-         {
-            AsynchronousFileTest.debug(20000 * 1000 / (System.currentTimeMillis() - lastTime) + " rec/sec (Async)");
-            lastTime = System.currentTimeMillis();
-         }
-
-      }
-
-      ActiveMQTestBase.waitForLatch(latchDone);
-
-      long timeTotal = System.currentTimeMillis() - valueInitial;
-
-      CountDownCallback.checkResults(numberOfLines, result);
-
-      AsynchronousFileTest.debug("After completions time = " + timeTotal +
-                                    " for " +
-                                    numberOfLines +
-                                    " registers " +
-                                    " size each line = " +
-                                    size +
-                                    ", Records/Sec=" +
-                                    numberOfLines *
-                                       1000 /
-                                       timeTotal +
-                                    " (Assynchronous)");
-
-      for (CountDownCallback tmp : list)
-      {
-         assertEquals(1, tmp.timesDoneCalled.get());
-         assertTrue(tmp.doneCalled);
-         assertEquals(0, tmp.errorCalled);
-      }
-
-      controller.close();
-   }
-
-   @Test
-   public void testDirectSynchronous() throws Exception
-   {
-
-      final int NUMBER_LINES = 3000;
-      final int SIZE = 1024;
-
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      controller.open(fileName, 2000);
-
-      buffer = AsynchronousFileImpl.newBuffer(SIZE);
-      encodeBufer(buffer);
-
-      preAlloc(controller, NUMBER_LINES * SIZE);
-
-      long startTime = System.currentTimeMillis();
-
-      for (int i = 0; i < NUMBER_LINES; i++)
-      {
-         CountDownLatch latchDone = new CountDownLatch(1);
-         CountDownCallback aioBlock = new CountDownCallback(latchDone, null, null, 0);
-         controller.write(i * 512, 512, buffer, aioBlock);
-         ActiveMQTestBase.waitForLatch(latchDone);
-         assertTrue(aioBlock.doneCalled);
-         assertEquals(0, aioBlock.errorCalled);
-      }
-
-      long timeTotal = System.currentTimeMillis() - startTime;
-      AsynchronousFileTest.debug("time = " + timeTotal +
-                                    " for " +
-                                    NUMBER_LINES +
-                                    " registers " +
-                                    " size each line = " +
-                                    SIZE +
-                                    " Records/Sec=" +
-                                    NUMBER_LINES *
-                                       1000 /
-                                       timeTotal +
-                                    " Synchronous");
-
-      controller.close();
-   }
-
-
-   @Test
-   public void testInternalWrite() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      controller.open(fileName, 2000);
-
-      final int SIZE = 10 * 512;
-
-      buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
-      for (int i = 0; i < SIZE; i++)
-      {
-         buffer.put(getSamplebyte(i));
-      }
-
-      controller.writeInternal(0, SIZE, buffer);
-
-      InputStream fileInput = new BufferedInputStream(new FileInputStream(new File(fileName)));
-
-      for (int i = 0; i < SIZE; i++)
-      {
-         assertEquals(getSamplebyte(i), fileInput.read());
-      }
-
-      assertEquals(-1, fileInput.read());
-
-   }
-
-
-   @Test
-   public void testInvalidWrite() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-      controller.open(fileName, 2000);
-
-      final int SIZE = 512;
-
-      buffer = AsynchronousFileImpl.newBuffer(SIZE);
-      encodeBufer(buffer);
-
-      preAlloc(controller, 10 * 512);
-
-      CountDownLatch latchDone = new CountDownLatch(1);
-
-      CountDownCallback aioBlock = new CountDownCallback(latchDone, null, null, 0);
-      controller.write(11, 512, buffer, aioBlock);
-
-      ActiveMQTestBase.waitForLatch(latchDone);
-
-      assertTrue(aioBlock.errorCalled != 0);
-      assertFalse(aioBlock.doneCalled);
-   }
-
-   @Test
-   public void testInvalidAlloc() throws Exception
-   {
-      try
-      {
-         @SuppressWarnings("unused")
-         ByteBuffer buffer = AsynchronousFileImpl.newBuffer(300);
-         fail("Exception expected");
-      }
-      catch (Exception ignored)
-      {
-      }
-
-   }
-
-   // This is in particular testing for http://bugs.sun.com/view_bug.do?bug_id=6791815
-   @Test
-   public void testAllocations() throws Exception
-   {
-      final AtomicInteger errors = new AtomicInteger(0);
-
-      Thread[] ts = new Thread[100];
-
-      final CountDownLatch align = new CountDownLatch(ts.length);
-      final CountDownLatch start = new CountDownLatch(1);
-
-      for (int i = 0; i < ts.length; i++)
-      {
-         ts[i] = new Thread()
-         {
-            @Override
-            public void run()
-            {
-               try
-               {
-                  align.countDown();
-                  start.await();
-                  for (int j = 0; j < 1000; j++)
-                  {
-                     ByteBuffer buffer = AsynchronousFileImpl.newBuffer(512);
-                     AsynchronousFileTest.destroy(buffer);
-                  }
-               }
-               catch (Throwable e)
-               {
-                  e.printStackTrace();
-                  errors.incrementAndGet();
-               }
-            }
-         };
-         ts[i].start();
-      }
-
-      align.await();
-      start.countDown();
-
-      for (Thread t : ts)
-      {
-         t.join();
-      }
-
-      assertEquals(0, errors.get());
-   }
-
-   @Test
-   public void testSize() throws Exception
-   {
-      controller = new AsynchronousFileImpl(executor, pollerExecutor);
-
-      final int NUMBER_LINES = 10;
-      final int SIZE = 1024;
-
-      controller.open(fileName, 1);
-
-      controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
-      assertEquals(NUMBER_LINES * SIZE, controller.size());
-   }
-
-   private static void addString(final String str, final ByteBuffer buffer)
-   {
-      CharBuffer charBuffer = CharBuffer.wrap(str);
-      AsynchronousFileTest.UTF_8_ENCODER.encode(charBuffer, buffer, true);
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java
index aa8422a..c9d3ce4 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java
@@ -16,10 +16,10 @@
  */
 package org.apache.activemq.artemis.tests.unit.core.asyncio;
 
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFile;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
@@ -55,7 +55,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
 
    static final int SIZE = 1024;
 
-   static final int NUMBER_OF_THREADS = 10;
+   static final int NUMBER_OF_THREADS = 1;
 
    static final int NUMBER_OF_LINES = 1000;
 
@@ -65,7 +65,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
 
    private static void debug(final String msg)
    {
-      UnitTestLogger.LOGGER.debug(msg);
+      UnitTestLogger.LOGGER.info(msg);
    }
 
    @Override
@@ -102,16 +102,18 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
    private void executeTest(final boolean sync) throws Throwable
    {
       MultiThreadAsynchronousFileTest.debug(sync ? "Sync test:" : "Async test");
-      AsynchronousFileImpl jlibAIO = new AsynchronousFileImpl(executor, pollerExecutor);
-      jlibAIO.open(fileName, 21000);
+      AIOSequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile(), 21000);
+      factory.start();
+      factory.disableBufferReuse();
+
+      AIOSequentialFile file = (AIOSequentialFile)factory.createSequentialFile(fileName);
+      file.open();
       try
       {
          MultiThreadAsynchronousFileTest.debug("Preallocating file");
 
-         jlibAIO.fill(0L,
-                      MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS,
-                      MultiThreadAsynchronousFileTest.SIZE * MultiThreadAsynchronousFileTest.NUMBER_OF_LINES,
-                      (byte) 0);
+         file.fill(MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS *
+                      MultiThreadAsynchronousFileTest.SIZE * MultiThreadAsynchronousFileTest.NUMBER_OF_LINES);
          MultiThreadAsynchronousFileTest.debug("Done Preallocating file");
 
          CountDownLatch latchStart = new CountDownLatch(MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS + 1);
@@ -119,7 +121,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
          ArrayList<ThreadProducer> list = new ArrayList<ThreadProducer>(MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS);
          for (int i = 0; i < MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS; i++)
          {
-            ThreadProducer producer = new ThreadProducer("Thread " + i, latchStart, jlibAIO, sync);
+            ThreadProducer producer = new ThreadProducer("Thread " + i, latchStart, file, sync);
             list.add(producer);
             producer.start();
          }
@@ -152,7 +154,8 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
       }
       finally
       {
-         jlibAIO.close();
+         file.close();
+         factory.stop();
       }
 
    }
@@ -170,11 +173,11 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
 
       boolean sync;
 
-      AsynchronousFileImpl libaio;
+      AIOSequentialFile libaio;
 
       public ThreadProducer(final String name,
                             final CountDownLatch latchStart,
-                            final AsynchronousFileImpl libaio,
+                            final AIOSequentialFile libaio,
                             final boolean sync)
       {
          super(name);
@@ -190,10 +193,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
 
          ByteBuffer buffer = null;
 
-         synchronized (MultiThreadAsynchronousFileTest.class)
-         {
-            buffer = AsynchronousFileImpl.newBuffer(MultiThreadAsynchronousFileTest.SIZE);
-         }
+         buffer = LibaioContext.newAlignedBuffer(MultiThreadAsynchronousFileTest.SIZE, 512);
 
          try
          {
@@ -268,7 +268,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
          {
             synchronized (MultiThreadAsynchronousFileTest.class)
             {
-               AsynchronousFileImpl.destroyBuffer(buffer);
+               LibaioContext.freeBuffer(buffer);
             }
          }
 
@@ -281,44 +281,9 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
       buffer.put(bytes);
    }
 
-   private void addData(final AsynchronousFileImpl aio, final ByteBuffer buffer, final AIOCallback callback) throws Exception
-   {
-      executor.execute(new WriteRunnable(aio, buffer, callback));
-   }
-
-   private class WriteRunnable implements Runnable
+   private void addData(final AIOSequentialFile aio, final ByteBuffer buffer, final IOCallback callback) throws Exception
    {
-
-      AsynchronousFileImpl aio;
-
-      ByteBuffer buffer;
-
-      AIOCallback callback;
-
-      public WriteRunnable(final AsynchronousFileImpl aio, final ByteBuffer buffer, final AIOCallback callback)
-      {
-         this.aio = aio;
-         this.buffer = buffer;
-         this.callback = callback;
-      }
-
-      public void run()
-      {
-         try
-         {
-            aio.write(getNewPosition() * MultiThreadAsynchronousFileTest.SIZE,
-                      MultiThreadAsynchronousFileTest.SIZE,
-                      buffer,
-                      callback);
-
-         }
-         catch (Exception e)
-         {
-            callback.onError(ActiveMQExceptionType.GENERIC_EXCEPTION.getCode(), e.toString());
-            e.printStackTrace();
-         }
-      }
-
+      aio.writeDirect(buffer, true, callback);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java
index aa5c68b..e08ef55 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java
@@ -37,8 +37,8 @@ import org.apache.activemq.artemis.core.journal.EncodingSupport;
 import org.apache.activemq.artemis.core.journal.LoaderCallback;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
 import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
@@ -100,7 +100,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
 
       FakeSequentialFileFactory factory = new FakeSequentialFileFactory(200, true);
 
-      SequentialFile file = factory.createSequentialFile("test1", 1);
+      SequentialFile file = factory.createSequentialFile("test1");
 
       file.open();
 
@@ -590,7 +590,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
 
       System.out.println("Files = " + factory.listFiles("tt"));
 
-      SequentialFile file = factory.createSequentialFile("tt-1.tt", 1);
+      SequentialFile file = factory.createSequentialFile("tt-1.tt");
 
       file.open();
 
@@ -656,7 +656,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
 
       journalImpl.appendCommitRecord(2L, false);
 
-      SequentialFile file = factory.createSequentialFile("tt-1.tt", 1);
+      SequentialFile file = factory.createSequentialFile("tt-1.tt");
 
       file.open();
 
@@ -761,7 +761,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
 
       journalImpl.appendCommitRecord(1L, false);
 
-      SequentialFile file = factory.createSequentialFile("tt-1.tt", 1);
+      SequentialFile file = factory.createSequentialFile("tt-1.tt");
 
       file.open();
 
@@ -1046,7 +1046,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
       Assert.assertEquals(0, records.size());
       Assert.assertEquals(1, transactions.size());
 
-      SequentialFile file = factory.createSequentialFile("tt-1.tt", 1);
+      SequentialFile file = factory.createSequentialFile("tt-1.tt");
 
       file.open();
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java
index e078043..c2f88ac 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java
@@ -19,10 +19,10 @@ package org.apache.activemq.artemis.tests.unit.core.journal.impl;
 import java.io.File;
 import java.nio.ByteBuffer;
 
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.junit.Assert;
@@ -44,7 +44,7 @@ public class CleanBufferTest extends ActiveMQTestBase
    @Test
    public void testCleanOnNIO()
    {
-      SequentialFileFactory factory = new NIOSequentialFileFactory(new File("Whatever"));
+      SequentialFileFactory factory = new NIOSequentialFileFactory(new File("Whatever"), 1);
 
       testBuffer(factory);
    }
@@ -52,9 +52,9 @@ public class CleanBufferTest extends ActiveMQTestBase
    @Test
    public void testCleanOnAIO()
    {
-      if (AsynchronousFileImpl.isLoaded())
+      if (LibaioContext.isLoaded())
       {
-         SequentialFileFactory factory = new AIOSequentialFileFactory(new File("Whatever"));
+         SequentialFileFactory factory = new AIOSequentialFileFactory(new File("Whatever"), 50);
 
          testBuffer(factory);
       }
@@ -70,6 +70,7 @@ public class CleanBufferTest extends ActiveMQTestBase
 
    private void testBuffer(final SequentialFileFactory factory)
    {
+      factory.start();
       ByteBuffer buffer = factory.newBuffer(100);
 
       try
@@ -107,6 +108,7 @@ public class CleanBufferTest extends ActiveMQTestBase
       finally
       {
          factory.releaseBuffer(buffer);
+         factory.stop();
       }
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java
index aaffffa..eabb89e 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java
@@ -17,7 +17,7 @@
 package org.apache.activemq.artemis.tests.unit.core.journal.impl;
 
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 
 public class FakeJournalImplTest extends JournalImplTestUnit
 {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java
index 7431233..aee1e06 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java
@@ -17,7 +17,7 @@
 package org.apache.activemq.artemis.tests.unit.core.journal.impl;
 
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 
 public class FakeSequentialFileFactoryTest extends SequentialFileFactoryTestBase
 {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java
index 8eacec1..73bf148 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java
@@ -15,15 +15,13 @@
  * limitations under the License.
  */
 package org.apache.activemq.artemis.tests.unit.core.journal.impl;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.junit.Before;
-
 import java.nio.ByteBuffer;
 
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.junit.Assert;
-
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.junit.Before;
 
 public abstract class FileFactoryTestBase extends ActiveMQTestBase
 {
@@ -42,15 +40,15 @@ public abstract class FileFactoryTestBase extends ActiveMQTestBase
 
    // Protected ---------------------------------
 
-   protected void checkFill(final SequentialFile file, final int pos, final int size, final byte fillChar) throws Exception
+   protected void checkFill(final SequentialFile file, final int size) throws Exception
    {
-      file.fill(pos, size, fillChar);
+      file.fill(size);
 
       file.close();
 
       file.open();
 
-      file.position(pos);
+      file.position(0);
 
       ByteBuffer bb = ByteBuffer.allocateDirect(size);
 
@@ -67,7 +65,7 @@ public abstract class FileFactoryTestBase extends ActiveMQTestBase
       for (int i = 0; i < size; i++)
       {
          // log.debug(" i is " + i);
-         Assert.assertEquals(fillChar, bytes[i]);
+         Assert.assertEquals(0, bytes[i]);
       }
 
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
index e340cf2..7e1347e 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
@@ -30,7 +30,7 @@ import org.apache.activemq.artemis.cli.commands.tools.EncodeJournal;
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.TestableJournal;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
@@ -104,6 +104,10 @@ public abstract class JournalImplTestBase extends ActiveMQTestBase
 
    protected void resetFileFactory() throws Exception
    {
+      if (fileFactory != null)
+      {
+         fileFactory.stop();
+      }
       fileFactory = getFileFactory();
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java
index ab86abc..b009092 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java
@@ -25,7 +25,7 @@ import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.SimpleEncoding;
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
 import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
 import org.apache.activemq.artemis.tests.util.RandomUtil;
@@ -42,7 +42,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
 
       for (String file : files)
       {
-         SequentialFile seqFile = fileFactory.createSequentialFile(file, 1);
+         SequentialFile seqFile = fileFactory.createSequentialFile(file);
          Assert.assertEquals(fileSize, seqFile.size());
       }
 
@@ -222,7 +222,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
       for (String fileStr : files)
       {
 
-         SequentialFile file = fileFactory.createSequentialFile(fileStr, 1);
+         SequentialFile file = fileFactory.createSequentialFile(fileStr);
 
          ByteBuffer buffer = fileFactory.newBuffer(JournalImpl.SIZE_HEADER);
 
@@ -284,7 +284,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
       long fileID = Integer.MAX_VALUE;
       for (String fileStr : files)
       {
-         SequentialFile file = fileFactory.createSequentialFile(fileStr, 1);
+         SequentialFile file = fileFactory.createSequentialFile(fileStr);
 
          file.open();
 
@@ -2138,6 +2138,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
       createJournal();
       startJournal();
       loadAndCheck();
+      stopJournal();
    }
 
    @Test

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java
index b5b721e..858227a 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java
@@ -27,7 +27,7 @@ import java.util.Set;
 
 import org.junit.Assert;
 
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
 import org.apache.activemq.artemis.core.journal.impl.Reclaimer;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java
index 469bdf2..60ca28d 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java
@@ -23,9 +23,9 @@ import java.util.UUID;
 
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.junit.After;
 import org.junit.Assert;
@@ -49,14 +49,14 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
    @After
    public void tearDown() throws Exception
    {
-      Assert.assertEquals(0, AsynchronousFileImpl.getTotalMaxIO());
-
       factory.stop();
 
       factory = null;
 
       ActiveMQTestBase.forceGC();
 
+      Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
+
       super.tearDown();
    }
 
@@ -86,7 +86,7 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
 
          expectedFiles.add(fileName);
 
-         SequentialFile sf = factory.createSequentialFile(fileName, 1);
+         SequentialFile sf = factory.createSequentialFile(fileName);
 
          sf.open();
 
@@ -98,10 +98,10 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
       // Create a couple with a different extension - they shouldn't be picked
       // up
 
-      SequentialFile sf1 = factory.createSequentialFile("different.file", 1);
+      SequentialFile sf1 = factory.createSequentialFile("different.file");
       sf1.open();
 
-      SequentialFile sf2 = factory.createSequentialFile("different.cheese", 1);
+      SequentialFile sf2 = factory.createSequentialFile("different.cheese");
       sf2.open();
 
       List<String> fileNames = factory.listFiles("amq");
@@ -132,22 +132,18 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
    @Test
    public void testFill() throws Exception
    {
-      SequentialFile sf = factory.createSequentialFile("fill.amq", 1);
+      SequentialFile sf = factory.createSequentialFile("fill.amq");
 
       sf.open();
 
       try
       {
 
-         checkFill(sf, 0, 2048, (byte)'X');
-
-         checkFill(sf, 512, 512, (byte)'Y');
-
-         checkFill(sf, 0, 1, (byte)'Z');
+         checkFill(sf, 2048);
 
-         checkFill(sf, 512, 1, (byte)'A');
+         checkFill(sf, 512);
 
-         checkFill(sf, 1024, 512 * 4, (byte)'B');
+         checkFill(sf, 512 * 4);
       }
       finally
       {
@@ -158,11 +154,11 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
    @Test
    public void testDelete() throws Exception
    {
-      SequentialFile sf = factory.createSequentialFile("delete-me.amq", 1);
+      SequentialFile sf = factory.createSequentialFile("delete-me.amq");
 
       sf.open();
 
-      SequentialFile sf2 = factory.createSequentialFile("delete-me2.amq", 1);
+      SequentialFile sf2 = factory.createSequentialFile("delete-me2.amq");
 
       sf2.open();
 
@@ -189,7 +185,7 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
    @Test
    public void testRename() throws Exception
    {
-      SequentialFile sf = factory.createSequentialFile("test1.amq", 1);
+      SequentialFile sf = factory.createSequentialFile("test1.amq");
 
       sf.open();
 
@@ -222,7 +218,7 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
    @Test
    public void testWriteandRead() throws Exception
    {
-      SequentialFile sf = factory.createSequentialFile("write.amq", 1);
+      SequentialFile sf = factory.createSequentialFile("write.amq");
 
       sf.open();
 
@@ -291,14 +287,14 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
    @Test
    public void testPosition() throws Exception
    {
-      SequentialFile sf = factory.createSequentialFile("position.amq", 1);
+      SequentialFile sf = factory.createSequentialFile("position.amq");
 
       sf.open();
 
       try
       {
 
-         sf.fill(0, 3 * 512, (byte)0);
+         sf.fill(3 * 512);
 
          String s1 = "orange";
          byte[] bytes1 = s1.getBytes(StandardCharsets.UTF_8);
@@ -376,11 +372,11 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
    @Test
    public void testOpenClose() throws Exception
    {
-      SequentialFile sf = factory.createSequentialFile("openclose.amq", 1);
+      SequentialFile sf = factory.createSequentialFile("openclose.amq");
 
       sf.open();
 
-      sf.fill(0, 512, (byte)0);
+      sf.fill(512);
 
       String s1 = "cheesecake";
       byte[] bytes1 = s1.getBytes(StandardCharsets.UTF_8);
@@ -418,15 +414,15 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
       return ActiveMQBuffers.wrappedBuffer(bytes);
    }
 
-   protected void checkFill(final SequentialFile file, final int pos, final int size, final byte fillChar) throws Exception
+   protected void checkFill(final SequentialFile file, final int size) throws Exception
    {
-      file.fill(pos, size, fillChar);
+      file.fill(size);
 
       file.close();
 
       file.open();
 
-      file.position(pos);
+      file.position(0);
 
       ByteBuffer bb = factory.newBuffer(size);
 
@@ -437,7 +433,7 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
       for (int i = 0; i < size; i++)
       {
          // log.debug(" i is " + i);
-         Assert.assertEquals(fillChar, bb.get(i));
+         Assert.assertEquals(0, bb.get(i));
       }
 
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java
index 76234b8..21866c6 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java
@@ -16,11 +16,6 @@
  */
 package org.apache.activemq.artemis.tests.unit.core.journal.impl;
 
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.junit.Test;
-
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.List;
@@ -28,11 +23,14 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
+import org.apache.activemq.artemis.core.io.buffer.TimedBufferObserver;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.junit.Assert;
-
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.impl.TimedBuffer;
-import org.apache.activemq.artemis.core.journal.impl.TimedBufferObserver;
+import org.junit.Test;
 
 public class TimedBufferTest extends ActiveMQTestBase
 {
@@ -49,7 +47,7 @@ public class TimedBufferTest extends ActiveMQTestBase
 
    // Public --------------------------------------------------------
 
-   IOAsyncTask dummyCallback = new IOAsyncTask()
+   IOCallback dummyCallback = new IOCallback()
    {
 
       public void done()
@@ -69,7 +67,7 @@ public class TimedBufferTest extends ActiveMQTestBase
       final AtomicInteger flushTimes = new AtomicInteger(0);
       class TestObserver implements TimedBufferObserver
       {
-         public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOAsyncTask> callbacks)
+         public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks)
          {
             buffers.add(buffer);
             flushTimes.incrementAndGet();
@@ -144,7 +142,7 @@ public class TimedBufferTest extends ActiveMQTestBase
       final AtomicInteger flushTimes = new AtomicInteger(0);
       class TestObserver implements TimedBufferObserver
       {
-         public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOAsyncTask> callbacks)
+         public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks)
          {
             buffers.add(buffer);
             flushTimes.incrementAndGet();
@@ -235,7 +233,7 @@ public class TimedBufferTest extends ActiveMQTestBase
    {
       class TestObserver implements TimedBufferObserver
       {
-         public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOAsyncTask> callbacks)
+         public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks)
          {
          }
 
@@ -321,7 +319,7 @@ public class TimedBufferTest extends ActiveMQTestBase
    {
       class TestObserver implements TimedBufferObserver
       {
-         public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOAsyncTask> callbacks)
+         public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks)
          {
          }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
index 59586fd..75a9535 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
@@ -27,12 +27,11 @@ import java.util.concurrent.ConcurrentHashMap;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
 import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.TimedBuffer;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
 
 public class FakeSequentialFileFactory implements SequentialFileFactory
 {
@@ -63,9 +62,16 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       this(1, false);
    }
 
+   @Override
+   public int getMaxIO()
+   {
+      return 1;
+   }
+
+
    // Public --------------------------------------------------------
 
-   public SequentialFile createSequentialFile(final String fileName, final int maxAIO)
+   public SequentialFile createSequentialFile(final String fileName)
    {
       FakeSequentialFile sf = fileMap.get(fileName);
 
@@ -233,11 +239,11 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
 
       final ByteBuffer bytes;
 
-      final IOAsyncTask callback;
+      final IOCallback callback;
 
       volatile boolean sendError;
 
-      CallbackRunnable(final FakeSequentialFile file, final ByteBuffer bytes, final IOAsyncTask callback)
+      CallbackRunnable(final FakeSequentialFile file, final ByteBuffer bytes, final IOCallback callback)
       {
          this.file = file;
          this.bytes = bytes;
@@ -260,11 +266,6 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
                {
                   callback.done();
                }
-
-               if (file.bufferCallback != null)
-               {
-                  file.bufferCallback.bufferDone(bytes);
-               }
             }
             catch (Throwable e)
             {
@@ -288,8 +289,6 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
 
       private ByteBuffer data;
 
-      private BufferCallback bufferCallback;
-
       public ByteBuffer getData()
       {
          return data;
@@ -321,14 +320,6 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
          notifyAll();
       }
 
-      public synchronized void waitForClose() throws Exception
-      {
-         while (open)
-         {
-            this.wait();
-         }
-      }
-
       public void delete()
       {
          if (open)
@@ -355,26 +346,21 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
          checkAndResize(0);
       }
 
-      public void setBufferCallback(final BufferCallback callback)
-      {
-         bufferCallback = callback;
-      }
-
-      public void fill(final int pos, final int size, final byte fillCharacter) throws Exception
+      public void fill(final int size) throws Exception
       {
          if (!open)
          {
             throw new IllegalStateException("Is closed");
          }
 
-         checkAndResize(pos + size);
+         checkAndResize(size);
 
          // log.debug("size is " + size + " pos is " + pos);
 
-         for (int i = pos; i < size + pos; i++)
+         for (int i = 0; i < size; i++)
          {
             byte[] array = data.array();
-            array[i] = fillCharacter;
+            array[i] = 0;
 
             // log.debug("Filling " + pos + " with char " + fillCharacter);
          }
@@ -385,7 +371,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
          return read(bytes, null);
       }
 
-      public int read(final ByteBuffer bytes, final IOAsyncTask callback) throws Exception
+      public int read(final ByteBuffer bytes, final IOCallback callback) throws Exception
       {
          if (!open)
          {
@@ -426,7 +412,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
          return data.position();
       }
 
-      public synchronized void writeDirect(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback)
+      public synchronized void writeDirect(final ByteBuffer bytes, final boolean sync, final IOCallback callback)
       {
          if (!open)
          {
@@ -485,7 +471,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#writeInternal(java.nio.ByteBuffer)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#writeInternal(java.nio.ByteBuffer)
        */
       public void writeInternal(ByteBuffer bytes) throws Exception
       {
@@ -555,7 +541,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#renameTo(org.apache.activemq.artemis.core.journal.SequentialFile)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#renameTo(org.apache.activemq.artemis.core.io.SequentialFile)
        */
       public void renameTo(final String newFileName) throws Exception
       {
@@ -565,7 +551,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#fits(int)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#fits(int)
        */
       public boolean fits(final int size)
       {
@@ -573,21 +559,21 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#setBuffering(boolean)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#setBuffering(boolean)
        */
       public void setBuffering(final boolean buffering)
       {
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#lockBuffer()
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#lockBuffer()
        */
       public void disableAutoFlush()
       {
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#unlockBuffer()
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#unlockBuffer()
        */
       public void enableAutoFlush()
       {
@@ -599,9 +585,9 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#write(org.apache.activemq.artemis.spi.core.remoting.ActiveMQBuffer, boolean, org.apache.activemq.artemis.core.journal.IOCallback)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#write(org.apache.activemq.artemis.spi.core.remoting.ActiveMQBuffer, boolean, org.apache.activemq.artemis.core.journal.IOCallback)
        */
-      public void write(final ActiveMQBuffer bytes, final boolean sync, final IOAsyncTask callback) throws Exception
+      public void write(final ActiveMQBuffer bytes, final boolean sync, final IOCallback callback) throws Exception
       {
          bytes.writerIndex(bytes.capacity());
          bytes.readerIndex(0);
@@ -610,7 +596,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#write(org.apache.activemq.artemis.spi.core.remoting.ActiveMQBuffer, boolean)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#write(org.apache.activemq.artemis.spi.core.remoting.ActiveMQBuffer, boolean)
        */
       public void write(final ActiveMQBuffer bytes, final boolean sync) throws Exception
       {
@@ -620,9 +606,9 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#write(org.apache.activemq.artemis.core.journal.EncodingSupport, boolean, org.apache.activemq.artemis.core.journal.IOCompletion)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#write(org.apache.activemq.artemis.core.journal.EncodingSupport, boolean, org.apache.activemq.artemis.core.journal.IOCompletion)
        */
-      public void write(final EncodingSupport bytes, final boolean sync, final IOAsyncTask callback) throws Exception
+      public void write(final EncodingSupport bytes, final boolean sync, final IOCallback callback) throws Exception
       {
          ByteBuffer buffer = newBuffer(bytes.getEncodeSize());
          ActiveMQBuffer outbuffer = ActiveMQBuffers.wrappedBuffer(buffer);
@@ -631,7 +617,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#write(org.apache.activemq.artemis.core.journal.EncodingSupport, boolean)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#write(org.apache.activemq.artemis.core.journal.EncodingSupport, boolean)
        */
       public void write(final EncodingSupport bytes, final boolean sync) throws Exception
       {
@@ -642,7 +628,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#exists()
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#exists()
        */
       public boolean exists()
       {
@@ -652,14 +638,14 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#setTimedBuffer(org.apache.activemq.artemis.core.journal.impl.TimedBuffer)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#setTimedBuffer(org.apache.activemq.artemis.core.io.buffer.TimedBuffer)
        */
       public void setTimedBuffer(final TimedBuffer buffer)
       {
       }
 
       /* (non-Javadoc)
-       * @see org.apache.activemq.artemis.core.journal.SequentialFile#copyTo(org.apache.activemq.artemis.core.journal.SequentialFile)
+       * @see org.apache.activemq.artemis.core.io.SequentialFile#copyTo(org.apache.activemq.artemis.core.io.SequentialFile)
        */
       public void copyTo(SequentialFile newFileName)
       {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java
index 8c4ff47..5accdac 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java
@@ -22,9 +22,9 @@ import java.util.List;
 
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
 import org.apache.activemq.artemis.core.paging.impl.Page;
 import org.apache.activemq.artemis.core.paging.impl.PagedMessageImpl;
@@ -52,14 +52,14 @@ public class PageTest extends ActiveMQTestBase
    public void testPageWithNIO() throws Exception
    {
       recreateDirectory(getTestDir());
-      testAdd(new NIOSequentialFileFactory(getTestDirfile()), 1000);
+      testAdd(new NIOSequentialFileFactory(getTestDirfile(), 1), 1000);
    }
 
    @Test
    public void testDamagedDataWithNIO() throws Exception
    {
       recreateDirectory(getTestDir());
-      testDamagedPage(new NIOSequentialFileFactory(getTestDirfile()), 1000);
+      testDamagedPage(new NIOSequentialFileFactory(getTestDirfile(), 1), 1000);
    }
 
    @Test
@@ -83,7 +83,7 @@ public class PageTest extends ActiveMQTestBase
    protected void testAdd(final SequentialFileFactory factory, final int numberOfElements) throws Exception
    {
 
-      SequentialFile file = factory.createSequentialFile("00010.page", 1);
+      SequentialFile file = factory.createSequentialFile("00010.page");
 
       Page impl = new Page(new SimpleString("something"), new NullStorageManager(), factory, file, 10);
 
@@ -100,7 +100,7 @@ public class PageTest extends ActiveMQTestBase
       impl.sync();
       impl.close();
 
-      file = factory.createSequentialFile("00010.page", 1);
+      file = factory.createSequentialFile("00010.page");
       file.open();
       impl = new Page(new SimpleString("something"), new NullStorageManager(), factory, file, 10);
 
@@ -130,7 +130,7 @@ public class PageTest extends ActiveMQTestBase
    protected void testDamagedPage(final SequentialFileFactory factory, final int numberOfElements) throws Exception
    {
 
-      SequentialFile file = factory.createSequentialFile("00010.page", 1);
+      SequentialFile file = factory.createSequentialFile("00010.page");
 
       Page impl = new Page(new SimpleString("something"), new NullStorageManager(), factory, file, 10);
 
@@ -172,7 +172,7 @@ public class PageTest extends ActiveMQTestBase
 
       impl.close();
 
-      file = factory.createSequentialFile("00010.page", 1);
+      file = factory.createSequentialFile("00010.page");
       file.open();
       impl = new Page(new SimpleString("something"), new NullStorageManager(), factory, file, 10);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
index 1a657c1..3863c12 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
@@ -34,9 +34,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
 import org.apache.activemq.artemis.core.paging.PagingManager;
@@ -129,7 +129,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase
    public void testPageWithNIO() throws Exception
    {
       ActiveMQTestBase.recreateDirectory(getTestDir());
-      testConcurrentPaging(new NIOSequentialFileFactory(new File(getTestDir())), 1);
+      testConcurrentPaging(new NIOSequentialFileFactory(new File(getTestDir()), 1), 1);
    }
 
    @Test
@@ -565,7 +565,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase
 
       for (String file : files)
       {
-         SequentialFile fileTmp = factory.createSequentialFile(file, 1);
+         SequentialFile fileTmp = factory.createSequentialFile(file);
          fileTmp.open();
          Assert.assertTrue("The page file size (" + fileTmp.size() + ") shouldn't be > " + MAX_SIZE,
                            fileTmp.size() <= MAX_SIZE);
@@ -645,7 +645,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase
    public void testRestartPage() throws Throwable
    {
       clearDataRecreateServerDirs();
-      SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()));
+      SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()), 1);
 
       PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
 
@@ -682,7 +682,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase
    public void testOrderOnPaging() throws Throwable
    {
       clearDataRecreateServerDirs();
-      SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()));
+      SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()), 1);
 
       PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java
index 3c1fb88..f89d61c 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java
@@ -25,7 +25,7 @@ import org.apache.activemq.artemis.core.journal.Journal;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.persistence.StorageManager;
 import org.apache.activemq.artemis.core.persistence.impl.journal.BatchingIDGenerator;
 import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
@@ -39,7 +39,7 @@ public class BatchIDGeneratorUnitTest extends ActiveMQTestBase
    @Test
    public void testSequence() throws Exception
    {
-      NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getTestDir()));
+      NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getTestDir()), 1);
       Journal journal = new JournalImpl(10 * 1024, 2, 0, 0, factory, "activemq-bindings", "bindings", 1);
 
       journal.start();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java
index 8e14647..f4abbaa 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java
@@ -23,8 +23,8 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
 import org.junit.Assert;
 import org.junit.Test;
@@ -52,7 +52,7 @@ public class OperationContextUnitTest extends ActiveMQTestBase
          final CountDownLatch latch1 = new CountDownLatch(1);
          final CountDownLatch latch2 = new CountDownLatch(1);
 
-         impl.executeOnCompletion(new IOAsyncTask()
+         impl.executeOnCompletion(new IOCallback()
          {
 
             public void onError(int errorCode, String errorMessage)
@@ -70,7 +70,7 @@ public class OperationContextUnitTest extends ActiveMQTestBase
          for (int i = 0; i < 10; i++) impl.storeLineUp();
          for (int i = 0; i < 3; i++) impl.pageSyncLineUp();
 
-         impl.executeOnCompletion(new IOAsyncTask()
+         impl.executeOnCompletion(new IOCallback()
          {
 
             public void onError(int errorCode, String errorMessage)
@@ -213,7 +213,7 @@ public class OperationContextUnitTest extends ActiveMQTestBase
       final AtomicInteger operations = new AtomicInteger(0);
 
       // We should be up to date with lineUps and executions. this should now just finish processing
-      context.executeOnCompletion(new IOAsyncTask()
+      context.executeOnCompletion(new IOCallback()
       {
 
          public void done()

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java
index 643e6c2..89c017b 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java
@@ -17,9 +17,9 @@
 package org.apache.activemq.artemis.tests.unit.core.server.impl;
 import java.io.File;
 
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.server.impl.AIOFileLockNodeManager;
 import org.apache.activemq.artemis.core.server.impl.FileLockNodeManager;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +47,7 @@ public class FileLockTest extends ActiveMQTestBase
    @Test
    public void testAIOLock() throws Exception
    {
-      if (AsynchronousFileImpl.isLoaded())
+      if (LibaioContext.isLoaded())
       {
          doTestLock(new AIOFileLockNodeManager(getTestDirfile(), false), new AIOFileLockNodeManager(getTestDirfile(), false));
       }


[8/9] activemq-artemis git commit: ARTEMIS-163 First pass on the native AIO refactoring

Posted by an...@apache.org.
ARTEMIS-163 First pass on the native AIO refactoring

https://issues.apache.org/jira/browse/ARTEMIS-163

On this pass I'm just converting the native layer to a simpler one.
It wasn't very easy to change the alignment at the current framework,
so I did some refactoring simplifying the native layer

The volume of the nubmer of changes here is because:

- The API is changed, we now don't close the libaio queue between files
- The native layer won't use malloc as much as it used to, saving some CPU and memory defragmentation
- I organized the code around nio and libaio


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/6fe9e0eb
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/6fe9e0eb
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/6fe9e0eb

Branch: refs/heads/master
Commit: 6fe9e0ebd6504897ba2b3ce7185cc63a0dbc8feb
Parents: 661f695
Author: Clebert Suconic <cl...@apache.org>
Authored: Mon Jul 27 16:15:03 2015 -0400
Committer: Clebert Suconic <cl...@apache.org>
Committed: Wed Jul 29 22:12:03 2015 -0400

----------------------------------------------------------------------
 .gitignore                                      |    2 +-
 CMakeLists.txt                                  |   18 +
 README.md                                       |    2 +-
 .../activemq/artemis/cli/commands/Create.java   |   90 +-
 .../cli/commands/tools/CompactJournal.java      |    6 +-
 .../cli/commands/tools/DecodeJournal.java       |    4 +-
 .../cli/commands/tools/EncodeJournal.java       |    6 +-
 .../cli/commands/tools/XmlDataExporter.java     |    6 +-
 .../cli/commands/util/SyncCalculation.java      |  190 ++++
 .../artemis/cli/commands/etc/broker.xml         |    1 +
 .../commands/etc/journal-buffer-settings.txt    |    8 +
 .../apache/activemq/cli/test/ArtemisTest.java   |   23 +-
 .../activemq/cli/test/StreamClassPathTest.java  |    1 +
 .../artemis/api/core/ActiveMQNativeIOError.java |    5 +
 .../journal/JMSJournalStorageManagerImpl.java   |    6 +-
 .../artemis/core/asyncio/AIOCallback.java       |   33 -
 .../artemis/core/asyncio/AsynchronousFile.java  |   58 -
 .../artemis/core/asyncio/BufferCallback.java    |   27 -
 .../core/asyncio/IOExceptionListener.java       |   22 -
 .../core/asyncio/impl/ActiveMQFileLock.java     |   47 -
 .../core/asyncio/impl/AsynchronousFileImpl.java |  822 --------------
 .../artemis/core/io/AbstractSequentialFile.java |  407 +++++++
 .../core/io/AbstractSequentialFileFactory.java  |  224 ++++
 .../activemq/artemis/core/io/DummyCallback.java |   49 +
 .../activemq/artemis/core/io/IOCallback.java    |   33 +
 .../core/io/IOCriticalErrorListener.java        |   25 +
 .../artemis/core/io/IOExceptionListener.java    |   22 +
 .../artemis/core/io/SequentialFile.java         |  116 ++
 .../artemis/core/io/SequentialFileFactory.java  |   91 ++
 .../artemis/core/io/aio/AIOSequentialFile.java  |  333 ++++++
 .../core/io/aio/AIOSequentialFileFactory.java   |  531 +++++++++
 .../artemis/core/io/aio/ActiveMQFileLock.java   |   47 +
 .../artemis/core/io/buffer/TimedBuffer.java     |  558 ++++++++++
 .../core/io/buffer/TimedBufferObserver.java     |   53 +
 .../artemis/core/io/nio/NIOSequentialFile.java  |  393 +++++++
 .../core/io/nio/NIOSequentialFileFactory.java   |  168 +++
 .../artemis/core/journal/IOAsyncTask.java       |   27 -
 .../artemis/core/journal/IOCompletion.java      |    4 +-
 .../core/journal/IOCriticalErrorListener.java   |   22 -
 .../activemq/artemis/core/journal/Journal.java  |    1 +
 .../artemis/core/journal/SequentialFile.java    |  129 ---
 .../core/journal/SequentialFileFactory.java     |   89 --
 .../core/journal/impl/AIOSequentialFile.java    |  326 ------
 .../journal/impl/AIOSequentialFileFactory.java  |  358 ------
 .../journal/impl/AbstractJournalUpdateTask.java |    8 +-
 .../journal/impl/AbstractSequentialFile.java    |  407 -------
 .../impl/AbstractSequentialFileFactory.java     |  218 ----
 .../core/journal/impl/DummyCallback.java        |   48 -
 .../core/journal/impl/FileWrapperJournal.java   |    2 +-
 .../artemis/core/journal/impl/JournalBase.java  |    1 +
 .../core/journal/impl/JournalCompactor.java     |    6 +-
 .../artemis/core/journal/impl/JournalFile.java  |    2 +-
 .../core/journal/impl/JournalFileImpl.java      |    2 +-
 .../journal/impl/JournalFilesRepository.java    |    8 +-
 .../artemis/core/journal/impl/JournalImpl.java  |   28 +-
 .../core/journal/impl/NIOSequentialFile.java    |  404 -------
 .../journal/impl/NIOSequentialFileFactory.java  |  168 ---
 .../core/journal/impl/SyncSpeedTest.java        |  354 ------
 .../artemis/core/journal/impl/TimedBuffer.java  |  558 ----------
 .../core/journal/impl/TimedBufferObserver.java  |   52 -
 .../core/journal/impl/TransactionCallback.java  |   12 +-
 .../artemis/core/io/aio/CallbackOrderTest.java  |   97 ++
 .../artemis/maven/ActiveMQCreatePlugin.java     |    1 +
 artemis-native/bin/libartemis-native-32.so      |  Bin 44082 -> 22260 bytes
 artemis-native/bin/libartemis-native-64.so      |  Bin 46624 -> 23984 bytes
 artemis-native/pom.xml                          |   24 +
 artemis-native/src/main/c/AIOController.cpp     |   63 --
 artemis-native/src/main/c/AIOController.h       |   51 -
 artemis-native/src/main/c/AIOException.h        |   75 --
 artemis-native/src/main/c/AsyncFile.cpp         |  348 ------
 artemis-native/src/main/c/AsyncFile.h           |   93 --
 artemis-native/src/main/c/CMakeLists.txt        |   26 +-
 artemis-native/src/main/c/CallbackAdapter.h     |   42 -
 artemis-native/src/main/c/JAIODatatypes.h       |   28 -
 .../src/main/c/JNICallbackAdapter.cpp           |   62 --
 artemis-native/src/main/c/JNICallbackAdapter.h  |   66 --
 .../src/main/c/JNI_AsynchronousFileImpl.cpp     |  377 -------
 artemis-native/src/main/c/JavaUtilities.cpp     |   62 --
 artemis-native/src/main/c/JavaUtilities.h       |   26 -
 artemis-native/src/main/c/LockClass.h           |   39 -
 artemis-native/src/main/c/Version.h             |   24 -
 artemis-native/src/main/c/exception_helper.h    |   23 +
 ...che_activemq_artemis_jlibaio_LibaioContext.c |  710 ++++++++++++
 .../activemq/artemis/core/libaio/Native.java    |   74 --
 .../activemq/artemis/jlibaio/LibaioContext.java |  446 ++++++++
 .../activemq/artemis/jlibaio/LibaioFile.java    |  152 +++
 .../activemq/artemis/jlibaio/NativeLogger.java  |   51 +
 .../activemq/artemis/jlibaio/SubmitInfo.java    |   25 +
 .../activemq/artemis/jlibaio/package-info.java  |   24 +
 .../artemis/jlibaio/util/CallbackCache.java     |   93 ++
 .../jlibaio/test/CallbackCachelTest.java        |  112 ++
 .../artemis/jlibaio/test/LibaioTest.java        |  859 +++++++++++++++
 .../plug/ProtonSessionIntegrationCallback.java  |    4 +-
 .../core/protocol/mqtt/MQTTPublishManager.java  |    4 +-
 .../openwire/OpenWireProtocolManager.java       |    4 +-
 .../protocol/stomp/StompProtocolManager.java    |    4 +-
 .../deployers/impl/FileConfigurationParser.java |    2 +-
 .../artemis/core/paging/PagingManager.java      |    2 +-
 .../artemis/core/paging/PagingStore.java        |    2 +-
 .../artemis/core/paging/PagingStoreFactory.java |    2 +-
 .../cursor/impl/PageSubscriptionImpl.java       |    6 +-
 .../activemq/artemis/core/paging/impl/Page.java |    4 +-
 .../core/paging/impl/PagingStoreFactoryNIO.java |    8 +-
 .../core/paging/impl/PagingStoreImpl.java       |   10 +-
 .../core/persistence/OperationContext.java      |    4 +-
 .../core/persistence/StorageManager.java        |    6 +-
 .../impl/journal/DescribeJournal.java           |    8 +-
 .../impl/journal/JournalStorageManager.java     |   33 +-
 .../impl/journal/LargeServerMessageImpl.java    |    2 +-
 .../impl/journal/LargeServerMessageInSync.java  |    4 +-
 .../impl/journal/OperationContextImpl.java      |   12 +-
 .../nullpm/NullStorageLargeServerMessage.java   |    2 +-
 .../impl/nullpm/NullStorageManager.java         |    8 +-
 .../core/postoffice/impl/PostOfficeImpl.java    |    6 +-
 .../core/ServerSessionPacketHandler.java        |    4 +-
 .../core/replication/ReplicatedJournal.java     |    2 +-
 .../core/replication/ReplicationEndpoint.java   |    6 +-
 .../core/replication/ReplicationManager.java    |    2 +-
 .../core/server/ActiveMQServerLogger.java       |   10 +-
 .../artemis/core/server/LargeServerMessage.java |    2 +-
 .../core/server/cluster/impl/Redistributor.java |    4 +-
 .../server/impl/AIOFileLockNodeManager.java     |   29 +-
 .../core/server/impl/ActiveMQServerImpl.java    |   18 +-
 .../artemis/core/server/impl/QueueImpl.java     |    4 +-
 .../core/server/impl/ServerSessionImpl.java     |    4 +-
 .../core/transaction/impl/TransactionImpl.java  |    8 +-
 .../artemis/tests/util/ActiveMQTestBase.java    |   66 +-
 .../tests/util/ColocatedActiveMQServer.java     |    7 +-
 .../integration/client/HangConsumerTest.java    |    6 +-
 .../integration/client/JournalCrashTest.java    |    4 +-
 .../client/LibaioDependencyCheckTest.java       |    4 +-
 .../tests/integration/client/PagingTest.java    |    8 +-
 .../client/RedeliveryConsumerTest.java          |    4 +-
 .../integration/cluster/bridge/BridgeTest.java  |    6 +-
 .../journal/AIOImportExportTest.java            |    6 +-
 .../journal/AIOJournalCompactTest.java          |    6 +-
 .../integration/journal/AIOJournalImplTest.java |   10 +-
 .../journal/AIOSequentialFileFactoryTest.java   |   10 +-
 .../journal/NIOBufferedJournalCompactTest.java  |    6 +-
 .../journal/NIOImportExportTest.java            |    6 +-
 .../journal/NIOJournalCompactTest.java          |   16 +-
 .../integration/journal/NIOJournalImplTest.java |    6 +-
 .../journal/NIONoBufferJournalImplTest.java     |    6 +-
 ...NIONonBufferedSequentialFileFactoryTest.java |    6 +-
 .../journal/NIOSequentialFileFactoryTest.java   |    6 +-
 .../journal/ValidateTransactionHealthTest.java  |   15 +-
 .../management/ActiveMQServerControlTest.java   |   12 +-
 .../replication/ReplicationTest.java            |   16 +-
 .../integration/server/FileLockTimeoutTest.java |    4 +-
 .../journal/FakeJournalImplTest.java            |    2 +-
 .../journal/JournalImplTestUnit.java            |   13 +-
 .../journal/RealJournalImplAIOTest.java         |    6 +-
 .../journal/RealJournalImplNIOTest.java         |    6 +-
 .../AIOAllPossibilitiesCompactStressTest.java   |    6 +-
 .../AIOMultiThreadCompactorStressTest.java      |    2 +-
 .../stress/journal/AddAndRemoveStressTest.java  |   16 +-
 .../stress/journal/CompactingStressTest.java    |   12 +-
 .../JournalCleanupCompactStressTest.java        |   50 +-
 .../stress/journal/MixupCompactorTestBase.java  |    6 +-
 .../NIOMultiThreadCompactorStressTest.java      |    8 +-
 .../core/journal/impl/AIOJournalImplTest.java   |    6 +-
 .../core/journal/impl/FakeJournalImplTest.java  |    2 +-
 .../core/journal/impl/JournalImplTestUnit.java  |   15 +-
 .../core/journal/impl/NIOJournalImplTest.java   |    6 +-
 .../tests/unit/core/asyncio/AIOTestBase.java    |   18 +-
 .../unit/core/asyncio/AsynchronousFileTest.java | 1015 ------------------
 .../MultiThreadAsynchronousFileTest.java        |   81 +-
 .../journal/impl/AlignedJournalImplTest.java    |   14 +-
 .../unit/core/journal/impl/CleanBufferTest.java |   16 +-
 .../core/journal/impl/FakeJournalImplTest.java  |    2 +-
 .../impl/FakeSequentialFileFactoryTest.java     |    2 +-
 .../core/journal/impl/FileFactoryTestBase.java  |   18 +-
 .../core/journal/impl/JournalImplTestBase.java  |    6 +-
 .../core/journal/impl/JournalImplTestUnit.java  |    9 +-
 .../unit/core/journal/impl/ReclaimerTest.java   |    2 +-
 .../impl/SequentialFileFactoryTestBase.java     |   52 +-
 .../unit/core/journal/impl/TimedBufferTest.java |   26 +-
 .../impl/fakes/FakeSequentialFileFactory.java   |   84 +-
 .../tests/unit/core/paging/impl/PageTest.java   |   18 +-
 .../core/paging/impl/PagingStoreImplTest.java   |   14 +-
 .../impl/BatchIDGeneratorUnitTest.java          |    4 +-
 .../impl/OperationContextUnitTest.java          |    8 +-
 .../unit/core/server/impl/FileLockTest.java     |    4 +-
 183 files changed, 6522 insertions(+), 7227 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 71af624..ce57485 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,4 @@ ratReport.txt
 **/cmake_install.cmake
 
 # this file is generated
-artemis-native/src/main/c/org_apache_activemq_artemis_core_libaio_Native.h
+artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.h

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..4681205
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,18 @@
+# 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.
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SUBDIRS(artemis-native)

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 65155f3..195441f 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ This file describes some minimum 'stuff one needs to know' to get started coding
 
 ## Source
 
-For details about the modifying the code, building the project, running tests, IDE integration, etc. see 
+For details about the modifying the code, building the project, running tests, IDE integration, etc. see
 our [Hacking Guide](./docs/hacking-guide/en/SUMMARY.md).
 
 ## Examples

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
index 7495ce2..2fdf5f2 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
@@ -26,6 +26,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.attribute.PosixFilePermission;
+import java.text.DecimalFormat;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -36,8 +37,10 @@ import java.util.regex.Pattern;
 import io.airlift.airline.Arguments;
 import io.airlift.airline.Command;
 import io.airlift.airline.Option;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
+import org.apache.activemq.artemis.cli.commands.util.SyncCalculation;
 import org.apache.activemq.artemis.core.server.cluster.impl.MessageLoadBalancingType;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
 
 import static java.nio.file.attribute.PosixFilePermission.GROUP_EXECUTE;
 import static java.nio.file.attribute.PosixFilePermission.GROUP_READ;
@@ -84,6 +87,7 @@ public class Create extends InputAbstract
    public static final String ETC_CLUSTER_SETTINGS_TXT = "etc/cluster-settings.txt";
    public static final String ETC_CONNECTOR_SETTINGS_TXT = "etc/connector-settings.txt";
    public static final String ETC_BOOTSTRAP_WEB_SETTINGS_TXT = "etc/bootstrap-web-settings.txt";
+   public static final String ETC_JOURNAL_BUFFER_SETTINGS = "etc/journal-buffer-settings.txt";
 
    @Arguments(description = "The instance directory to hold the broker's configuration and data.  Path must be writable.", required = true)
    File directory;
@@ -142,6 +146,9 @@ public class Create extends InputAbstract
    @Option(name = "--require-login", description = "This will configure security to require user / password, opposite of --allow-anonymous")
    Boolean requireLogin = null;
 
+   @Option(name = "--no-sync-test", description = "Disable the calculation for the buffer")
+   boolean noSyncTest;
+
    @Option(name = "--user", description = "The username (Default: input)")
    String user;
 
@@ -529,12 +536,16 @@ public class Create extends InputAbstract
          filters.put("${shared-store.settings}", "");
       }
 
-      if (IS_WINDOWS || !AsynchronousFileImpl.isLoaded())
+      boolean aio;
+
+      if (IS_WINDOWS || !supportsLibaio())
       {
+         aio = false;
          filters.put("${journal.settings}", "NIO");
       }
       else
       {
+         aio = true;
          filters.put("${journal.settings}", "ASYNCIO");
       }
 
@@ -590,7 +601,8 @@ public class Create extends InputAbstract
       new File(directory, "etc").mkdirs();
       new File(directory, "log").mkdirs();
       new File(directory, "tmp").mkdirs();
-      new File(directory, "data").mkdirs();
+      File dataFolder = new File(directory, "data");
+      dataFolder.mkdirs();
 
       if (javaOptions == null || javaOptions.length() == 0)
       {
@@ -638,7 +650,7 @@ public class Create extends InputAbstract
          filters.put("${bootstrap-web-settings}", applyFilters(readTextFile(ETC_BOOTSTRAP_WEB_SETTINGS_TXT), filters));
       }
 
-
+      performSyncCalc(filters, aio, dataFolder);
 
       write(ETC_BOOTSTRAP_XML, filters, false);
       write(ETC_BROKER_XML, filters, false);
@@ -694,6 +706,76 @@ public class Create extends InputAbstract
       return null;
    }
 
+   private void performSyncCalc(HashMap<String, String> filters, boolean aio, File dataFolder)
+   {
+      if (noSyncTest)
+      {
+         filters.put("${journal-buffer.settings}", "");
+      }
+      else
+      {
+         try
+         {
+            int writes = 250;
+            System.out.println("");
+            System.out.println("Performing write sync calculation...");
+
+            long time = SyncCalculation.syncTest(dataFolder, 4096, writes, 5, verbose, aio);
+            long nanoseconds = SyncCalculation.toNanos(time, writes);
+            double writesPerMillisecond = (double)writes / (double) time;
+
+            String writesPerMillisecondStr = new DecimalFormat("###.##").format(writesPerMillisecond);
+
+            HashMap<String, String> syncFilter = new HashMap<String, String>();
+            syncFilter.put("${nanoseconds}", Long.toString(nanoseconds));
+            syncFilter.put("${writesPerMillisecond}", writesPerMillisecondStr);
+
+            System.out.println("done! Your system can make " + writesPerMillisecondStr +
+                    " writes per millisecond, your journal-buffer-timeout will be " + nanoseconds);
+
+            filters.put("${journal-buffer.settings}", applyFilters(readTextFile(ETC_JOURNAL_BUFFER_SETTINGS), syncFilter));
+
+         }
+         catch (Exception e)
+         {
+            filters.put("${journal-buffer.settings}", "");
+            e.printStackTrace();
+            System.err.println("Couldn't perform sync calculation, using default values");
+         }
+      }
+   }
+
+   private boolean supportsLibaio()
+   {
+      if (LibaioContext.isLoaded())
+      {
+         try (LibaioContext context = new LibaioContext(1, true))
+         {
+            File tmpFile = new File(directory, "validateAIO.bin");
+            boolean supportsLibaio = true;
+            try
+            {
+               LibaioFile file = context.openFile(tmpFile, true);
+               file.close();
+            }
+            catch (Exception e)
+            {
+               supportsLibaio = false;
+            }
+            tmpFile.delete();
+            if (!supportsLibaio)
+            {
+               System.err.println("The filesystem used on " + directory + " doesn't support libAIO and O_DIRECT files, switching journal-type to NIO");
+            }
+            return supportsLibaio;
+         }
+      }
+      else
+      {
+         return false;
+      }
+   }
+
    private void makeExec(String path) throws IOException
    {
       try

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
index 0239998..38fb785 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
@@ -22,9 +22,9 @@ import io.airlift.airline.Command;
 import org.apache.activemq.artemis.cli.commands.Action;
 import org.apache.activemq.artemis.cli.commands.ActionContext;
 import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 
 @Command(name = "compact", description = "Compacts the journal of a non running server")
 public final class CompactJournal extends DataAbstract implements Action
@@ -54,7 +54,7 @@ public final class CompactJournal extends DataAbstract implements Action
                                      final int fileSize,
                                      final IOCriticalErrorListener listener) throws Exception
    {
-      NIOSequentialFileFactory nio = new NIOSequentialFileFactory(directory, listener);
+      NIOSequentialFileFactory nio = new NIOSequentialFileFactory(directory, listener, 1);
 
       JournalImpl journal = new JournalImpl(fileSize, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
index 5b28a18..6b608c3 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
@@ -35,7 +35,7 @@ import org.apache.activemq.artemis.cli.commands.Configurable;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
 import org.apache.activemq.artemis.core.journal.impl.JournalRecord;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.utils.Base64;
 
 @Command(name = "decode", description = "Decode a journal's internal format into a new journal set of files")
@@ -117,7 +117,7 @@ public class DecodeJournal extends Configurable implements Action
             System.err.println("Could not create directory " + directory);
       }
 
-      NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null);
+      NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null, 1);
 
       JournalImpl journal = new JournalImpl(fileSize, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
index 8b0721b..a408951 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
@@ -28,11 +28,11 @@ import org.apache.activemq.artemis.cli.commands.Action;
 import org.apache.activemq.artemis.cli.commands.ActionContext;
 import org.apache.activemq.artemis.cli.commands.Configurable;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
 import org.apache.activemq.artemis.core.journal.impl.JournalReaderCallback;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.utils.Base64;
 
 @Command(name = "encode", description = "Encode a set of journal files into an internal encoded data format")
@@ -113,7 +113,7 @@ public class EncodeJournal extends Configurable implements Action
                                     final int fileSize,
                                     final PrintStream out) throws Exception
    {
-      NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null);
+      NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null, 1);
 
       JournalImpl journal = new JournalImpl(fileSize, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
index e099a0b..cf5be12 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
@@ -52,10 +52,10 @@ import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
 import org.apache.activemq.artemis.core.journal.Journal;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.message.BodyEncoder;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
 import org.apache.activemq.artemis.core.paging.PagingManager;
@@ -345,7 +345,7 @@ public final class XmlDataExporter extends DataAbstract implements Action
 
    private void getJmsBindings() throws Exception
    {
-      SequentialFileFactory bindingsJMS = new NIOSequentialFileFactory(config.getBindingsLocation());
+      SequentialFileFactory bindingsJMS = new NIOSequentialFileFactory(config.getBindingsLocation(), 1);
 
       Journal jmsJournal = new JournalImpl(1024 * 1024,
                                            2,

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java
new file mode 100644
index 0000000..b5a8845
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java
@@ -0,0 +1,190 @@
+/**
+ * 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.activemq.artemis.cli.commands.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.text.DecimalFormat;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.utils.ReusableLatch;
+
+/**
+ * It will perform a simple test to evaluate how many syncs a disk can make per second
+ * * *
+ */
+public class SyncCalculation
+{
+   /**
+    * It will perform a write test of blockSize * bocks, sinc on each write, for N tries.
+    * It will return the lowest spent time from the tries.
+    */
+   public static long syncTest(File datafolder, int blockSize, int blocks, int tries, boolean verbose, boolean aio) throws Exception
+   {
+      SequentialFileFactory factory = newFactory(datafolder, aio);
+      SequentialFile file = factory.createSequentialFile("test.tmp");
+
+      try
+      {
+         file.delete();
+         file.open();
+
+         file.fill(blockSize * blocks);
+
+         long[] result = new long[tries];
+
+         byte[] block = new byte[blockSize];
+
+         for (int i = 0; i < block.length; i++)
+         {
+            block[i] = (byte) 't';
+         }
+
+         ByteBuffer bufferBlock = factory.newBuffer(blockSize);
+         bufferBlock.put(block);
+         bufferBlock.position(0);
+
+         final ReusableLatch latch = new ReusableLatch(0);
+
+         IOCallback callback = new IOCallback()
+         {
+            @Override
+            public void done()
+            {
+               latch.countDown();
+            }
+
+            @Override
+            public void onError(int errorCode, String errorMessage)
+            {
+
+            }
+         };
+
+         DecimalFormat dcformat = new DecimalFormat("###.##");
+         for (int ntry = 0; ntry < tries; ntry++)
+         {
+
+            if (verbose)
+            {
+               System.out.println("**************************************************");
+               System.out.println(ntry + " of " + tries + " calculation");
+            }
+            file.position(0);
+            long start = System.currentTimeMillis();
+            for (int i = 0; i < blocks; i++)
+            {
+               bufferBlock.position(0);
+               latch.countUp();
+               file.writeDirect(bufferBlock, true, callback);
+               if (!latch.await(5, TimeUnit.SECONDS))
+               {
+                  throw new IOException("Callback wasn't called");
+               }
+            }
+            long end = System.currentTimeMillis();
+
+            result[ntry] = (end - start);
+
+            if (verbose)
+            {
+               double writesPerMillisecond = (double)blocks / (double) result[ntry];
+               System.out.println("Time = " + result[ntry]);
+               System.out.println("Writes / millisecond = " + dcformat.format(writesPerMillisecond));
+               System.out.println("bufferTimeout = " + toNanos(result[ntry], blocks));
+               System.out.println("**************************************************");
+            }
+         }
+
+         factory.releaseDirectBuffer(bufferBlock);
+
+         long totalTime = Long.MAX_VALUE;
+         for (int i = 0; i < tries; i++)
+         {
+            if (result[i] < totalTime)
+            {
+               totalTime = result[i];
+            }
+         }
+
+         return totalTime;
+      }
+      finally
+      {
+         try
+         {
+            file.close();
+         }
+         catch (Exception e)
+         {
+         }
+         try
+         {
+            file.delete();
+         }
+         catch (Exception e)
+         {
+         }
+         try
+         {
+            factory.stop();
+         }
+         catch (Exception e)
+         {
+         }
+      }
+   }
+
+
+   public static long toNanos(long time, long blocks)
+   {
+
+      double blocksPerMillisecond = (double) blocks / (double) (time);
+
+      long nanoSeconds = TimeUnit.NANOSECONDS.convert(1, TimeUnit.MILLISECONDS);
+
+      long timeWait = (long) (nanoSeconds / blocksPerMillisecond);
+
+      return timeWait;
+   }
+
+   private static SequentialFileFactory newFactory(File datafolder, boolean aio)
+   {
+      if (aio && LibaioContext.isLoaded())
+      {
+         SequentialFileFactory factory = new AIOSequentialFileFactory(datafolder, 1);
+         factory.start();
+         ((AIOSequentialFileFactory) factory).disableBufferReuse();
+
+         return factory;
+      }
+      else
+      {
+         SequentialFileFactory factory = new NIOSequentialFileFactory(datafolder, 1);
+         factory.start();
+         return factory;
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
index 52d665e..1cd3245 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
@@ -42,6 +42,7 @@ under the License.
       <large-messages-directory>${data.dir}/large-messages</large-messages-directory>
 
       <journal-min-files>10</journal-min-files>
+${journal-buffer.settings}
 ${connector-config.settings}
       <acceptors>
          <!-- Default ActiveMQ Artemis Acceptor.  Multi-protocol adapter.  Currently supports Core, OpenWire, Stomp and AMQP. -->

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/journal-buffer-settings.txt
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/journal-buffer-settings.txt b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/journal-buffer-settings.txt
new file mode 100644
index 0000000..566c29e
--- /dev/null
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/journal-buffer-settings.txt
@@ -0,0 +1,8 @@
+
+      <!--
+       This value was determined through a calculation.
+       Your system could perform ${writesPerMillisecond} writes per millisecond
+       on the current journal configuration.
+       That translates as a sync write every ${nanoseconds} nanoseconds
+      -->
+      <journal-buffer-timeout>${nanoseconds}</journal-buffer-timeout>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
index 99c8f23..3aed71e 100644
--- a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
+++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
@@ -25,6 +25,8 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.activemq.artemis.cli.Artemis;
 import org.apache.activemq.artemis.cli.commands.Run;
+import org.apache.activemq.artemis.cli.commands.util.SyncCalculation;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
 import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
 import org.junit.After;
@@ -69,15 +71,29 @@ public class ArtemisTest
    }
 
    @Test
+   public void testSync() throws Exception
+   {
+      int writes = 2560;
+      int tries = 10;
+      long totalAvg = SyncCalculation.syncTest(temporaryFolder.getRoot(), 4096, writes, tries, true, true);
+      System.out.println();
+      System.out.println("TotalAvg = " + totalAvg);
+      long nanoTime = SyncCalculation.toNanos(totalAvg, writes);
+      System.out.println("nanoTime avg = " + nanoTime);
+      Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
+
+   }
+
+   @Test
    public void testSimpleRun() throws Exception
    {
       Run.setEmbedded(true);
       Artemis.main("create", temporaryFolder.getRoot().getAbsolutePath(), "--force", "--silent-input", "--no-web");
       System.setProperty("artemis.instance", temporaryFolder.getRoot().getAbsolutePath());
       // Some exceptions may happen on the initialization, but they should be ok on start the basic core protocol
-      Artemis.main("run");
-      Assert.assertEquals(Integer.valueOf(70), Artemis.execute("producer", "--txt-size", "50", "--message-count", "70", "--verbose"));
-      Assert.assertEquals(Integer.valueOf(70), Artemis.execute("consumer", "--txt-size", "50", "--verbose", "--break-on-null", "--receive-timeout", "100"));
+      Artemis.execute("run");
+      Assert.assertEquals(Integer.valueOf(1000), Artemis.execute("producer", "--message-count", "1000", "--verbose"));
+      Assert.assertEquals(Integer.valueOf(1000), Artemis.execute("consumer", "--verbose", "--break-on-null", "--receive-timeout", "100"));
 
       ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616");
       Connection connection = cf.createConnection();
@@ -116,6 +132,7 @@ public class ArtemisTest
 
       Artemis.execute("stop");
       Assert.assertTrue(Run.latchRunning.await(5, TimeUnit.SECONDS));
+      Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
 
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
index 632e2c0..0ee3afb 100644
--- a/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
+++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
@@ -49,6 +49,7 @@ public class StreamClassPathTest
       openStream(Create.ETC_CLUSTER_SETTINGS_TXT);
       openStream(Create.ETC_CONNECTOR_SETTINGS_TXT);
       openStream(Create.ETC_BOOTSTRAP_WEB_SETTINGS_TXT);
+      openStream(Create.ETC_JOURNAL_BUFFER_SETTINGS);
    }
 
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java
index 8a47dfa..e69a7fd 100644
--- a/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java
@@ -34,4 +34,9 @@ public final class ActiveMQNativeIOError extends ActiveMQException
    {
       super(ActiveMQExceptionType.NATIVE_ERROR_CANT_INITIALIZE_AIO, msg);
    }
+
+   public ActiveMQNativeIOError(String msg, Throwable e)
+   {
+      super(ActiveMQExceptionType.NATIVE_ERROR_CANT_INITIALIZE_AIO, msg, e);
+   }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java
index b3ef038..2d884e7 100644
--- a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java
+++ b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java
@@ -29,9 +29,9 @@ import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.journal.Journal;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.replication.ReplicatedJournal;
 import org.apache.activemq.artemis.core.replication.ReplicationManager;
 import org.apache.activemq.artemis.core.server.JournalType;
@@ -87,7 +87,7 @@ public final class JMSJournalStorageManagerImpl implements JMSStorageManager
 
       createDir = config.isCreateBindingsDir();
 
-      SequentialFileFactory bindingsJMS = new NIOSequentialFileFactory(config.getBindingsLocation());
+      SequentialFileFactory bindingsJMS = new NIOSequentialFileFactory(config.getBindingsLocation(), 1);
 
       Journal localJMS = new JournalImpl(1024 * 1024,
                                          2,

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AIOCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AIOCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AIOCallback.java
deleted file mode 100644
index 80aa753..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AIOCallback.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.activemq.artemis.core.asyncio;
-
-/**
- * The interface used for AIO Callbacks.
- */
-public interface AIOCallback
-{
-   /**
-    * Method for sync notifications. When this callback method is called, there is a guarantee the data is written on the disk.
-    * <br><b>Note:</b><i>Leave this method as soon as possible, or you would be blocking the whole notification thread</i> */
-   void done();
-
-   /**
-    * Method for error notifications.
-    * Observation: The whole file will be probably failing if this happens. Like, if you delete the file, you will start to get errors for these operations*/
-   void onError(int errorCode, String errorMessage);
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AsynchronousFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AsynchronousFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AsynchronousFile.java
deleted file mode 100644
index 52b8e05..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AsynchronousFile.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.activemq.artemis.core.asyncio;
-
-import java.nio.ByteBuffer;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-
-public interface AsynchronousFile
-{
-   void close() throws InterruptedException, ActiveMQException;
-
-   /**
-    *
-    * Note: If you are using a native Linux implementation, maxIO can't be higher than what's defined on /proc/sys/fs/aio-max-nr, or you would get an error
-    * @param fileName
-    * @param maxIO The number of max concurrent asynchronous IO operations. It has to be balanced between the size of your writes and the capacity of your disk.
-    * @throws ActiveMQException
-    */
-   void open(String fileName, int maxIO) throws ActiveMQException;
-
-   /**
-    * Warning: This function will perform a synchronous IO, probably translating to a fstat call
-    * @throws ActiveMQException
-    * */
-   long size() throws ActiveMQException;
-
-   /** Any error will be reported on the callback interface */
-   void write(long position, long size, ByteBuffer directByteBuffer, AIOCallback aioCallback);
-
-   /**
-    * Performs an internal direct write.
-    * @throws ActiveMQException
-    */
-   void writeInternal(long positionToWrite, long size, ByteBuffer bytes) throws ActiveMQException;
-
-   void read(long position, long size, ByteBuffer directByteBuffer, AIOCallback aioCallback) throws ActiveMQException;
-
-   void fill(long position, int blocks, long size, byte fillChar) throws ActiveMQException;
-
-   void setBufferCallback(BufferCallback callback);
-
-   int getBlockSize();
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/BufferCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/BufferCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/BufferCallback.java
deleted file mode 100644
index e7b0ca5..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/BufferCallback.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.activemq.artemis.core.asyncio;
-
-import java.nio.ByteBuffer;
-
-/**
- * Used to receive a notification on completed buffers used by the AIO layer.
- */
-public interface BufferCallback
-{
-   void bufferDone(ByteBuffer buffer);
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/IOExceptionListener.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/IOExceptionListener.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/IOExceptionListener.java
deleted file mode 100644
index 0cfe945..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/IOExceptionListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.activemq.artemis.core.asyncio;
-
-public interface IOExceptionListener
-{
-   void onIOException(Exception exception, String message);
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/ActiveMQFileLock.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/ActiveMQFileLock.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/ActiveMQFileLock.java
deleted file mode 100644
index 0af3152..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/ActiveMQFileLock.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.activemq.artemis.core.asyncio.impl;
-
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-
-import org.apache.activemq.artemis.core.libaio.Native;
-
-public class ActiveMQFileLock extends FileLock
-{
-
-   private final int handle;
-
-   protected ActiveMQFileLock(final int handle)
-   {
-      super((FileChannel)null, 0, 0, false);
-      this.handle = handle;
-   }
-
-   @Override
-   public boolean isValid()
-   {
-      return true;
-   }
-
-   @Override
-   public void release() throws IOException
-   {
-      Native.closeFile(handle);
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/AsynchronousFileImpl.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/AsynchronousFileImpl.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/AsynchronousFileImpl.java
deleted file mode 100644
index be4d885..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/AsynchronousFileImpl.java
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * 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.activemq.artemis.core.asyncio.impl;
-
-import java.nio.ByteBuffer;
-import java.nio.channels.FileLock;
-import java.util.PriorityQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-import org.apache.activemq.artemis.core.asyncio.AsynchronousFile;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
-import org.apache.activemq.artemis.core.asyncio.IOExceptionListener;
-import org.apache.activemq.artemis.core.libaio.Native;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-import org.apache.activemq.artemis.utils.ReusableLatch;
-
-/**
- * AsynchronousFile implementation
- *
- *         Warning: Case you refactor the name or the package of this class
- *         You need to make sure you also rename the C++ native calls
- */
-public class AsynchronousFileImpl implements AsynchronousFile
-{
-   // Static ----------------------------------------------------------------------------
-
-   private static final AtomicInteger totalMaxIO = new AtomicInteger(0);
-
-   private static boolean loaded = false;
-
-   /**
-    * This definition needs to match Version.h on the native sources.
-    * <br>
-    * Or else the native module won't be loaded because of version mismatches
-    */
-   private static final int EXPECTED_NATIVE_VERSION = 52;
-
-   /**
-    * Used to determine the next writing sequence
-    */
-   private final AtomicLong nextWritingSequence = new AtomicLong(0);
-
-   /**
-    * Used to determine the next writing sequence.
-    * This is accessed from a single thread (the Poller Thread)
-    */
-   private long nextReadSequence = 0;
-
-   /**
-    * AIO can't guarantee ordering over callbacks.
-    * <br>
-    * We use this {@link PriorityQueue} to hold values until they are in order
-    */
-   private final PriorityQueue<CallbackHolder> pendingCallbacks = new PriorityQueue<CallbackHolder>();
-
-   public static void addMax(final int io)
-   {
-      AsynchronousFileImpl.totalMaxIO.addAndGet(io);
-   }
-
-   /**
-    * For test purposes
-    */
-   public static int getTotalMaxIO()
-   {
-      return AsynchronousFileImpl.totalMaxIO.get();
-   }
-
-   public static void resetMaxAIO()
-   {
-      AsynchronousFileImpl.totalMaxIO.set(0);
-   }
-
-   public static int openFile(String fileName)
-   {
-      return Native.openFile(fileName);
-   }
-
-   public static void closeFile(int handle)
-   {
-      Native.closeFile(handle);
-   }
-
-   public static void destroyBuffer(ByteBuffer buffer)
-   {
-      Native.destroyBuffer(buffer);
-   }
-
-   private static boolean loadLibrary(final String name)
-   {
-      try
-      {
-         ActiveMQJournalLogger.LOGGER.trace(name + " being loaded");
-         System.loadLibrary(name);
-         if (Native.getNativeVersion() != AsynchronousFileImpl.EXPECTED_NATIVE_VERSION)
-         {
-            ActiveMQJournalLogger.LOGGER.incompatibleNativeLibrary();
-            return false;
-         }
-         else
-         {
-            return true;
-         }
-      }
-      catch (Throwable e)
-      {
-         ActiveMQJournalLogger.LOGGER.debug(name + " -> error loading the native library", e);
-         return false;
-      }
-
-   }
-
-   static
-   {
-      String[] libraries = new String[]{"artemis-native", "artemis-native-64", "artemis-native-32"};
-
-      for (String library : libraries)
-      {
-         if (AsynchronousFileImpl.loadLibrary(library))
-         {
-            AsynchronousFileImpl.loaded = true;
-            break;
-         }
-         else
-         {
-            ActiveMQJournalLogger.LOGGER.debug("Library " + library + " not found!");
-         }
-      }
-
-      if (!AsynchronousFileImpl.loaded)
-      {
-         ActiveMQJournalLogger.LOGGER.debug("Couldn't locate LibAIO Wrapper");
-      }
-   }
-
-   public static boolean isLoaded()
-   {
-      return AsynchronousFileImpl.loaded;
-   }
-
-   // Attributes ------------------------------------------------------------------------
-
-   private boolean opened = false;
-
-   private String fileName;
-
-   /**
-    * Used while inside the callbackDone and callbackError
-    */
-   private final Lock callbackLock = new ReentrantLock();
-
-   private final ReusableLatch pollerLatch = new ReusableLatch();
-
-   private volatile Runnable poller;
-
-   private int maxIO;
-
-   private final Lock writeLock = new ReentrantReadWriteLock().writeLock();
-
-   private final ReusableLatch pendingWrites = new ReusableLatch();
-
-   private Semaphore maxIOSemaphore;
-
-   private BufferCallback bufferCallback;
-
-   /**
-    * A callback for IO errors when they happen
-    */
-   private final IOExceptionListener ioExceptionListener;
-
-   /**
-    * Warning: Beware of the C++ pointer! It will bite you! :-)
-    */
-   private ByteBuffer handler;
-
-   // A context switch on AIO would make it to synchronize the disk before
-   // switching to the new thread, what would cause
-   // serious performance problems. Because of that we make all the writes on
-   // AIO using a single thread.
-   private final Executor writeExecutor;
-
-   private final Executor pollerExecutor;
-
-   // AsynchronousFile implementation ---------------------------------------------------
-
-   /**
-    * @param writeExecutor  It needs to be a single Thread executor. If null it will use the user thread to execute write operations
-    * @param pollerExecutor The thread pool that will initialize poller handlers
-    */
-   public AsynchronousFileImpl(final Executor writeExecutor, final Executor pollerExecutor, final IOExceptionListener ioExceptionListener)
-   {
-      this.writeExecutor = writeExecutor;
-      this.pollerExecutor = pollerExecutor;
-      this.ioExceptionListener = ioExceptionListener;
-   }
-
-   public AsynchronousFileImpl(final Executor writeExecutor, final Executor pollerExecutor)
-   {
-      this(writeExecutor, pollerExecutor, null);
-   }
-
-   public void open(final String fileName1, final int maxIOArgument) throws ActiveMQException
-   {
-      writeLock.lock();
-
-      try
-      {
-         if (opened)
-         {
-            throw new IllegalStateException("AsynchronousFile is already opened");
-         }
-
-         this.maxIO = maxIOArgument;
-         maxIOSemaphore = new Semaphore(this.maxIO);
-
-         this.fileName = fileName1;
-
-         try
-         {
-            handler = Native.init(AsynchronousFileImpl.class, fileName1, this.maxIO, ActiveMQJournalLogger.LOGGER);
-         }
-         catch (ActiveMQException e)
-         {
-            ActiveMQException ex = null;
-            if (e.getType() == ActiveMQExceptionType.NATIVE_ERROR_CANT_INITIALIZE_AIO)
-            {
-               ex = new ActiveMQException(e.getType(),
-                                         "Can't initialize AIO. Currently AIO in use = " + AsynchronousFileImpl.totalMaxIO.get() +
-                                            ", trying to allocate more " +
-                                            maxIOArgument,
-                                         e);
-            }
-            else
-            {
-               ex = e;
-            }
-            throw ex;
-         }
-         opened = true;
-         AsynchronousFileImpl.addMax(this.maxIO);
-         nextWritingSequence.set(0);
-         nextReadSequence = 0;
-      }
-      finally
-      {
-         writeLock.unlock();
-      }
-   }
-
-   public void close() throws InterruptedException, ActiveMQException
-   {
-      checkOpened();
-
-      writeLock.lock();
-
-      try
-      {
-
-         while (!pendingWrites.await(60000))
-         {
-            ActiveMQJournalLogger.LOGGER.couldNotGetLock(fileName);
-         }
-
-         while (!maxIOSemaphore.tryAcquire(maxIO, 60, TimeUnit.SECONDS))
-         {
-            ActiveMQJournalLogger.LOGGER.couldNotGetLock(fileName);
-         }
-
-         maxIOSemaphore = null;
-         if (poller != null)
-         {
-            stopPoller();
-         }
-
-         if (handler != null)
-         {
-            Native.closeInternal(handler);
-            AsynchronousFileImpl.addMax(-maxIO);
-         }
-         opened = false;
-         handler = null;
-      }
-      finally
-      {
-         writeLock.unlock();
-      }
-   }
-
-
-   public void writeInternal(long positionToWrite, long size, ByteBuffer bytes) throws ActiveMQException
-   {
-      try
-      {
-         Native.writeInternal(handler, positionToWrite, size, bytes);
-      }
-      catch (ActiveMQException e)
-      {
-         fireExceptionListener(e.getType().getCode(), e.getMessage());
-         throw e;
-      }
-      if (bufferCallback != null)
-      {
-         bufferCallback.bufferDone(bytes);
-      }
-   }
-
-
-   public void write(final long position,
-                     final long size,
-                     final ByteBuffer directByteBuffer,
-                     final AIOCallback aioCallback)
-   {
-      if (aioCallback == null)
-      {
-         throw new NullPointerException("Null Callback");
-      }
-
-      checkOpened();
-      if (poller == null)
-      {
-         startPoller();
-      }
-
-      pendingWrites.countUp();
-
-      if (writeExecutor != null)
-      {
-         maxIOSemaphore.acquireUninterruptibly();
-
-         writeExecutor.execute(new Runnable()
-         {
-            public void run()
-            {
-               long sequence = nextWritingSequence.getAndIncrement();
-
-               try
-               {
-                  Native.write(AsynchronousFileImpl.this, handler, sequence, position, size, directByteBuffer, aioCallback);
-               }
-               catch (ActiveMQException e)
-               {
-                  callbackError(aioCallback, sequence, directByteBuffer, e.getType().getCode(), e.getMessage());
-               }
-               catch (RuntimeException e)
-               {
-                  callbackError(aioCallback,
-                                sequence,
-                                directByteBuffer,
-                                ActiveMQExceptionType.INTERNAL_ERROR.getCode(),
-                                e.getMessage());
-               }
-            }
-         });
-      }
-      else
-      {
-         maxIOSemaphore.acquireUninterruptibly();
-
-         long sequence = nextWritingSequence.getAndIncrement();
-
-         try
-         {
-            Native.write(this, handler, sequence, position, size, directByteBuffer, aioCallback);
-         }
-         catch (ActiveMQException e)
-         {
-            callbackError(aioCallback, sequence, directByteBuffer, e.getType().getCode(), e.getMessage());
-         }
-         catch (RuntimeException e)
-         {
-            callbackError(aioCallback, sequence, directByteBuffer, ActiveMQExceptionType.INTERNAL_ERROR.getCode(), e.getMessage());
-         }
-      }
-
-   }
-
-   public void read(final long position,
-                    final long size,
-                    final ByteBuffer directByteBuffer,
-                    final AIOCallback aioPackage) throws ActiveMQException
-   {
-      checkOpened();
-      if (poller == null)
-      {
-         startPoller();
-      }
-      pendingWrites.countUp();
-      maxIOSemaphore.acquireUninterruptibly();
-      try
-      {
-         Native.read(this, handler, position, size, directByteBuffer, aioPackage);
-      }
-      catch (ActiveMQException e)
-      {
-         // Release only if an exception happened
-         maxIOSemaphore.release();
-         pendingWrites.countDown();
-         throw e;
-      }
-      catch (RuntimeException e)
-      {
-         // Release only if an exception happened
-         maxIOSemaphore.release();
-         pendingWrites.countDown();
-         throw e;
-      }
-   }
-
-   public long size() throws ActiveMQException
-   {
-      checkOpened();
-      return Native.size0(handler);
-   }
-
-   public void fill(final long position, final int blocks, final long size, final byte fillChar) throws ActiveMQException
-   {
-      checkOpened();
-      try
-      {
-         Native.fill(handler, position, blocks, size, fillChar);
-      }
-      catch (ActiveMQException e)
-      {
-         fireExceptionListener(e.getType().getCode(), e.getMessage());
-         throw e;
-      }
-   }
-
-   public int getBlockSize()
-   {
-      return 512;
-   }
-
-   /**
-    * This needs to be synchronized because of
-    * http://bugs.sun.com/view_bug.do?bug_id=6791815
-    * http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2009-January/000386.html
-    */
-   public static synchronized ByteBuffer newBuffer(final int size)
-   {
-      if (size % 512 != 0)
-      {
-         throw new RuntimeException("Buffer size needs to be aligned to 512");
-      }
-
-      return Native.newNativeBuffer(size);
-   }
-
-   public void setBufferCallback(final BufferCallback callback)
-   {
-      bufferCallback = callback;
-   }
-
-   /**
-    * Return the JNI handler used on C++
-    */
-   public ByteBuffer getHandler()
-   {
-      return handler;
-   }
-
-   public static void clearBuffer(final ByteBuffer buffer)
-   {
-      Native.resetBuffer(buffer, buffer.limit());
-      buffer.position(0);
-   }
-
-   // Protected -------------------------------------------------------------------------
-
-   @Override
-   protected void finalize()
-   {
-      if (opened)
-      {
-         ActiveMQJournalLogger.LOGGER.fileFinalizedWhileOpen(fileName);
-      }
-   }
-
-   // Private ---------------------------------------------------------------------------
-
-   private void callbackDone(final AIOCallback callback, final long sequence, final ByteBuffer buffer)
-   {
-      maxIOSemaphore.release();
-
-      pendingWrites.countDown();
-
-      callbackLock.lock();
-
-      try
-      {
-
-         if (sequence == -1)
-         {
-            callback.done();
-         }
-         else
-         {
-            if (sequence == nextReadSequence)
-            {
-               nextReadSequence++;
-               callback.done();
-               flushCallbacks();
-            }
-            else
-            {
-               pendingCallbacks.add(new CallbackHolder(sequence, callback));
-            }
-         }
-
-         // The buffer is not sent on callback for read operations
-         if (bufferCallback != null && buffer != null)
-         {
-            bufferCallback.bufferDone(buffer);
-         }
-      }
-      finally
-      {
-         callbackLock.unlock();
-      }
-   }
-
-   private void flushCallbacks()
-   {
-      while (!pendingCallbacks.isEmpty() && pendingCallbacks.peek().sequence == nextReadSequence)
-      {
-         CallbackHolder holder = pendingCallbacks.poll();
-         if (holder.isError())
-         {
-            ErrorCallback error = (ErrorCallback) holder;
-            holder.callback.onError(error.errorCode, error.message);
-         }
-         else
-         {
-            holder.callback.done();
-         }
-         nextReadSequence++;
-      }
-   }
-
-   // Called by the JNI layer.. just ignore the
-   // warning
-   private void callbackError(final AIOCallback callback,
-                              final long sequence,
-                              final ByteBuffer buffer,
-                              final int errorCode,
-                              final String errorMessage)
-   {
-      ActiveMQJournalLogger.LOGGER.callbackError(errorMessage);
-
-      fireExceptionListener(errorCode, errorMessage);
-
-      maxIOSemaphore.release();
-
-      pendingWrites.countDown();
-
-      callbackLock.lock();
-
-      try
-      {
-         if (sequence == -1)
-         {
-            callback.onError(errorCode, errorMessage);
-         }
-         else
-         {
-            if (sequence == nextReadSequence)
-            {
-               nextReadSequence++;
-               callback.onError(errorCode, errorMessage);
-               flushCallbacks();
-            }
-            else
-            {
-               pendingCallbacks.add(new ErrorCallback(sequence, callback, errorCode, errorMessage));
-            }
-         }
-      }
-      finally
-      {
-         callbackLock.unlock();
-      }
-
-      // The buffer is not sent on callback for read operations
-      if (bufferCallback != null && buffer != null)
-      {
-         bufferCallback.bufferDone(buffer);
-      }
-   }
-
-   /**
-    * This is called by the native layer
-    *
-    * @param errorCode
-    * @param errorMessage
-    */
-   private void fireExceptionListener(final int errorCode, final String errorMessage)
-   {
-      ActiveMQJournalLogger.LOGGER.ioError(errorCode, errorMessage);
-      if (ioExceptionListener != null)
-      {
-         ioExceptionListener.onIOException(ActiveMQExceptionType.getType(errorCode).createException(errorMessage), errorMessage);
-      }
-   }
-
-   private void pollEvents()
-   {
-      if (!opened)
-      {
-         return;
-      }
-      Native.internalPollEvents(handler);
-   }
-
-   private void startPoller()
-   {
-      writeLock.lock();
-
-      try
-      {
-
-         if (poller == null)
-         {
-            pollerLatch.countUp();
-            poller = new PollerRunnable();
-            try
-            {
-               pollerExecutor.execute(poller);
-            }
-            catch (Exception ex)
-            {
-               ActiveMQJournalLogger.LOGGER.errorStartingPoller(ex);
-            }
-         }
-      }
-      finally
-      {
-         writeLock.unlock();
-      }
-   }
-
-   private void checkOpened()
-   {
-      if (!opened)
-      {
-         throw new RuntimeException("File is not opened");
-      }
-   }
-
-   /**
-    * @throws ActiveMQException
-    * @throws InterruptedException
-    */
-   private void stopPoller() throws ActiveMQException, InterruptedException
-   {
-      Native.stopPoller(handler);
-      // We need to make sure we won't call close until Poller is
-      // completely done, or we might get beautiful GPFs
-      pollerLatch.await();
-   }
-
-   public static FileLock lock(int handle)
-   {
-      if (Native.flock(handle))
-      {
-         return new ActiveMQFileLock(handle);
-      }
-      else
-      {
-         return null;
-      }
-   }
-
-   // Native ----------------------------------------------------------------------------
-
-
-   /**
-    * Explicitly adding a compare to clause that returns 0 for at least the same object.
-    * <br>
-    * If {@link Comparable#compareTo(Object)} does not return 0 -for at least the same object- some
-    * Collection classes methods will fail (example {@link PriorityQueue#remove(Object)}. If it
-    * returns 0, then {@link #equals(Object)} must return {@code true} for the exact same cases,
-    * otherwise we will get compatibility problems between Java5 and Java6.
-    */
-   private static class CallbackHolder implements Comparable<CallbackHolder>
-   {
-      final long sequence;
-
-      final AIOCallback callback;
-
-      public boolean isError()
-      {
-         return false;
-      }
-
-      public CallbackHolder(final long sequence, final AIOCallback callback)
-      {
-         this.sequence = sequence;
-         this.callback = callback;
-      }
-
-      public int compareTo(final CallbackHolder o)
-      {
-         // It shouldn't be equals in any case
-         if (this == o)
-            return 0;
-         if (sequence <= o.sequence)
-         {
-            return -1;
-         }
-         else
-         {
-            return 1;
-         }
-      }
-
-      /**
-       * See {@link CallbackHolder}.
-       */
-      @Override
-      public int hashCode()
-      {
-         return super.hashCode();
-      }
-
-      /**
-       * See {@link CallbackHolder}.
-       */
-      @Override
-      public boolean equals(Object obj)
-      {
-         return super.equals(obj);
-      }
-   }
-
-   private static final class ErrorCallback extends CallbackHolder
-   {
-      final int errorCode;
-
-      final String message;
-
-      @Override
-      public boolean isError()
-      {
-         return true;
-      }
-
-      public ErrorCallback(final long sequence, final AIOCallback callback, final int errorCode, final String message)
-      {
-         super(sequence, callback);
-
-         this.errorCode = errorCode;
-
-         this.message = message;
-      }
-
-      /**
-       * See {@link CallbackHolder}.
-       */
-      @Override
-      public int hashCode()
-      {
-         return super.hashCode();
-      }
-
-      /**
-       * See {@link CallbackHolder}.
-       */
-      @Override
-      public boolean equals(Object obj)
-      {
-         return super.equals(obj);
-      }
-   }
-
-   private class PollerRunnable implements Runnable
-   {
-      PollerRunnable()
-      {
-      }
-
-      public void run()
-      {
-         try
-         {
-            pollEvents();
-         }
-         finally
-         {
-            // This gives us extra protection in cases of interruption
-            // Case the poller thread is interrupted, this will allow us to
-            // restart the thread when required
-            poller = null;
-            pollerLatch.countDown();
-         }
-      }
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFile.java
new file mode 100644
index 0000000..acc0732
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFile.java
@@ -0,0 +1,407 @@
+/*
+ * 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.activemq.artemis.core.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
+import org.apache.activemq.artemis.core.journal.EncodingSupport;
+import org.apache.activemq.artemis.core.journal.impl.SimpleWaitIOCallback;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
+import org.apache.activemq.artemis.core.io.buffer.TimedBufferObserver;
+import org.apache.activemq.artemis.journal.ActiveMQJournalBundle;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+
+public abstract class AbstractSequentialFile implements SequentialFile
+{
+
+   private File file;
+
+   protected final File directory;
+
+   protected final SequentialFileFactory factory;
+
+   protected long fileSize = 0;
+
+   protected final AtomicLong position = new AtomicLong(0);
+
+   protected TimedBuffer timedBuffer;
+
+   /**
+    * Instead of having AIOSequentialFile implementing the Observer, I have done it on an inner class.
+    * This is the class returned to the factory when the file is being activated.
+    */
+   protected final TimedBufferObserver timedBufferObserver = new LocalBufferObserver();
+
+   /**
+    * Used for asynchronous writes
+    */
+   protected final Executor writerExecutor;
+
+   /**
+    * @param file
+    * @param directory
+    */
+   public AbstractSequentialFile(final File directory,
+                                 final String file,
+                                 final SequentialFileFactory factory,
+                                 final Executor writerExecutor)
+   {
+      super();
+      this.file = new File(directory, file);
+      this.directory = directory;
+      this.factory = factory;
+      this.writerExecutor = writerExecutor;
+   }
+
+   // Public --------------------------------------------------------
+
+   public final boolean exists()
+   {
+      return file.exists();
+   }
+
+   public final String getFileName()
+   {
+      return file.getName();
+   }
+
+   public final void delete() throws IOException, InterruptedException, ActiveMQException
+   {
+      if (isOpen())
+      {
+         close();
+      }
+
+      if (file.exists() && !file.delete())
+      {
+         ActiveMQJournalLogger.LOGGER.errorDeletingFile(this);
+      }
+   }
+
+   public void copyTo(SequentialFile newFileName) throws Exception
+   {
+      try
+      {
+         ActiveMQJournalLogger.LOGGER.debug("Copying " + this + " as " + newFileName);
+         if (!newFileName.isOpen())
+         {
+            newFileName.open();
+         }
+
+         if (!isOpen())
+         {
+            this.open();
+         }
+
+
+         ByteBuffer buffer = ByteBuffer.allocate(10 * 1024);
+
+         for (;;)
+         {
+            buffer.rewind();
+            int size = this.read(buffer);
+            newFileName.writeDirect(buffer, false);
+            if (size < 10 * 1024)
+            {
+               break;
+            }
+         }
+         newFileName.close();
+         this.close();
+      }
+      catch (IOException e)
+      {
+         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+         throw e;
+      }
+   }
+
+   /**
+    * @throws IOException only declare exception due to signature. Sub-class needs it.
+    */
+   @Override
+   public void position(final long pos) throws IOException
+   {
+      position.set(pos);
+   }
+
+   public long position()
+   {
+      return position.get();
+   }
+
+   public final void renameTo(final String newFileName) throws IOException, InterruptedException,
+      ActiveMQException
+   {
+      try
+      {
+         close();
+      }
+      catch (IOException e)
+      {
+         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+         throw e;
+      }
+
+      File newFile = new File(directory + "/" + newFileName);
+
+      if (!file.equals(newFile))
+      {
+         if (!file.renameTo(newFile))
+         {
+            throw ActiveMQJournalBundle.BUNDLE.ioRenameFileError(file.getName(), newFileName);
+         }
+         file = newFile;
+      }
+   }
+
+   /**
+    * @throws IOException      we declare throwing IOException because sub-classes need to do it
+    * @throws ActiveMQException
+    */
+   public synchronized void close() throws IOException, InterruptedException, ActiveMQException
+   {
+      final CountDownLatch donelatch = new CountDownLatch(1);
+
+      if (writerExecutor != null)
+      {
+         writerExecutor.execute(new Runnable()
+         {
+            public void run()
+            {
+               donelatch.countDown();
+            }
+         });
+
+         while (!donelatch.await(60, TimeUnit.SECONDS))
+         {
+            ActiveMQJournalLogger.LOGGER.couldNotCompleteTask(new Exception("trace"), file.getName());
+         }
+      }
+   }
+
+   public final boolean fits(final int size)
+   {
+      if (timedBuffer == null)
+      {
+         return position.get() + size <= fileSize;
+      }
+      else
+      {
+         return timedBuffer.checkSize(size);
+      }
+   }
+
+   public void setTimedBuffer(final TimedBuffer buffer)
+   {
+      if (timedBuffer != null)
+      {
+         timedBuffer.setObserver(null);
+      }
+
+      timedBuffer = buffer;
+
+      if (buffer != null)
+      {
+         buffer.setObserver(timedBufferObserver);
+      }
+
+   }
+
+   public void write(final ActiveMQBuffer bytes, final boolean sync, final IOCallback callback) throws IOException
+   {
+      if (timedBuffer != null)
+      {
+         bytes.setIndex(0, bytes.capacity());
+         timedBuffer.addBytes(bytes, sync, callback);
+      }
+      else
+      {
+         ByteBuffer buffer = factory.newBuffer(bytes.capacity());
+         buffer.put(bytes.toByteBuffer().array());
+         buffer.rewind();
+         writeDirect(buffer, sync, callback);
+      }
+   }
+
+   public void write(final ActiveMQBuffer bytes, final boolean sync) throws IOException, InterruptedException,
+      ActiveMQException
+   {
+      if (sync)
+      {
+         SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
+
+         write(bytes, true, completion);
+
+         completion.waitCompletion();
+      }
+      else
+      {
+         write(bytes, false, DummyCallback.getInstance());
+      }
+   }
+
+   public void write(final EncodingSupport bytes, final boolean sync, final IOCallback callback)
+   {
+      if (timedBuffer != null)
+      {
+         timedBuffer.addBytes(bytes, sync, callback);
+      }
+      else
+      {
+         ByteBuffer buffer = factory.newBuffer(bytes.getEncodeSize());
+
+         // If not using the TimedBuffer, a final copy is necessary
+         // Because AIO will need a specific Buffer
+         // And NIO will also need a whole buffer to perform the write
+
+         ActiveMQBuffer outBuffer = ActiveMQBuffers.wrappedBuffer(buffer);
+         bytes.encode(outBuffer);
+         buffer.rewind();
+         writeDirect(buffer, sync, callback);
+      }
+   }
+
+   public void write(final EncodingSupport bytes, final boolean sync) throws InterruptedException, ActiveMQException
+   {
+      if (sync)
+      {
+         SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
+
+         write(bytes, true, completion);
+
+         completion.waitCompletion();
+      }
+      else
+      {
+         write(bytes, false, DummyCallback.getInstance());
+      }
+   }
+
+   protected File getFile()
+   {
+      return file;
+   }
+
+   private static final class DelegateCallback implements IOCallback
+   {
+      final List<IOCallback> delegates;
+
+      private DelegateCallback(final List<IOCallback> delegates)
+      {
+         this.delegates = delegates;
+      }
+
+      public void done()
+      {
+         for (IOCallback callback : delegates)
+         {
+            try
+            {
+               callback.done();
+            }
+            catch (Throwable e)
+            {
+               ActiveMQJournalLogger.LOGGER.errorCompletingCallback(e);
+            }
+         }
+      }
+
+      public void onError(final int errorCode, final String errorMessage)
+      {
+         for (IOCallback callback : delegates)
+         {
+            try
+            {
+               callback.onError(errorCode, errorMessage);
+            }
+            catch (Throwable e)
+            {
+               ActiveMQJournalLogger.LOGGER.errorCallingErrorCallback(e);
+            }
+         }
+      }
+   }
+
+   protected ByteBuffer newBuffer(int size, int limit)
+   {
+      size = factory.calculateBlockSize(size);
+      limit = factory.calculateBlockSize(limit);
+
+      ByteBuffer buffer = factory.newBuffer(size);
+      buffer.limit(limit);
+      return buffer;
+   }
+
+   protected class LocalBufferObserver implements TimedBufferObserver
+   {
+      public void flushBuffer(final ByteBuffer buffer, final boolean requestedSync, final List<IOCallback> callbacks)
+      {
+         buffer.flip();
+
+         if (buffer.limit() == 0)
+         {
+            factory.releaseBuffer(buffer);
+         }
+         else
+         {
+            writeDirect(buffer, requestedSync, new DelegateCallback(callbacks));
+         }
+      }
+
+      public ByteBuffer newBuffer(final int size, final int limit)
+      {
+         return AbstractSequentialFile.this.newBuffer(size, limit);
+      }
+
+      public int getRemainingBytes()
+      {
+         if (fileSize - position.get() > Integer.MAX_VALUE)
+         {
+            return Integer.MAX_VALUE;
+         }
+         else
+         {
+            return (int)(fileSize - position.get());
+         }
+      }
+
+      @Override
+      public String toString()
+      {
+         return "TimedBufferObserver on file (" + getFile().getName() + ")";
+      }
+
+   }
+
+   @Override
+   public File getJavaFile()
+   {
+      return getFile().getAbsoluteFile();
+   }
+}


[6/9] activemq-artemis git commit: ARTEMIS-163 First pass on the native AIO refactoring

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java
index b85a845..d0140f1 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java
@@ -16,7 +16,9 @@
  */
 package org.apache.activemq.artemis.core.journal;
 
-public interface IOCompletion extends IOAsyncTask
+import org.apache.activemq.artemis.core.io.IOCallback;
+
+public interface IOCompletion extends IOCallback
 {
    void storeLineUp();
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCriticalErrorListener.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCriticalErrorListener.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCriticalErrorListener.java
deleted file mode 100644
index fc0bbf9..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCriticalErrorListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal;
-
-public interface IOCriticalErrorListener
-{
-   void onIOException(Exception code, String message, SequentialFile file);
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java
index f3335b0..6b0beab 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java
@@ -19,6 +19,7 @@ package org.apache.activemq.artemis.core.journal;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.server.ActiveMQComponent;
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFile.java
deleted file mode 100644
index 34e6d02..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFile.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.journal.impl.TimedBuffer;
-
-public interface SequentialFile
-{
-   /*
-    * Creates the file if it doesn't already exist, then opens it
-    */
-   void open() throws Exception;
-
-   boolean isOpen();
-
-   boolean exists();
-
-   /**
-    * The maximum number of simultaneous writes accepted
-    * @param maxIO
-    * @throws Exception
-    */
-   void open(int maxIO, boolean useExecutor) throws Exception;
-
-   boolean fits(int size);
-
-   int getAlignment() throws Exception;
-
-   int calculateBlockStart(int position) throws Exception;
-
-   String getFileName();
-
-   void fill(int position, int size, byte fillCharacter) throws Exception;
-
-   void delete() throws IOException, InterruptedException, ActiveMQException;
-
-   void write(ActiveMQBuffer bytes, boolean sync, IOAsyncTask callback) throws Exception;
-
-   void write(ActiveMQBuffer bytes, boolean sync) throws Exception;
-
-   void write(EncodingSupport bytes, boolean sync, IOAsyncTask callback) throws Exception;
-
-   void write(EncodingSupport bytes, boolean sync) throws Exception;
-
-   /**
-    * Write directly to the file without using any buffer
-    * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
-    *           NIO). To be safe, use a buffer from the corresponding
-    *           {@link SequentialFileFactory#newBuffer(int)}.
-    */
-   void writeDirect(ByteBuffer bytes, boolean sync, IOAsyncTask callback);
-
-   /**
-    * Write directly to the file without using any buffer
-    * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
-    *           NIO). To be safe, use a buffer from the corresponding
-    *           {@link SequentialFileFactory#newBuffer(int)}.
-    */
-   void writeDirect(ByteBuffer bytes, boolean sync) throws Exception;
-
-   /**
-    * Write directly to the file. This is used by compacting and other places where we write a big
-    * buffer in a single shot. writeInternal should always block until the entire write is sync on
-    * disk.
-    * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
-    *           NIO). To be safe, use a buffer from the corresponding
-    *           {@link SequentialFileFactory#newBuffer(int)}.
-    */
-   void writeInternal(ByteBuffer bytes) throws Exception;
-
-   /**
-    * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
-    *           NIO). To be safe, use a buffer from the corresponding
-    *           {@link SequentialFileFactory#newBuffer(int)}.
-    */
-   int read(ByteBuffer bytes, IOAsyncTask callback) throws Exception;
-
-   /**
-    * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
-    *           NIO). To be safe, use a buffer from the corresponding
-    *           {@link SequentialFileFactory#newBuffer(int)}.
-    */
-   int read(ByteBuffer bytes) throws Exception;
-
-   void position(long pos) throws IOException;
-
-   long position();
-
-   void close() throws Exception;
-
-   void waitForClose() throws Exception;
-
-   void sync() throws IOException;
-
-   long size() throws Exception;
-
-   void renameTo(String newFileName) throws Exception;
-
-   SequentialFile cloneFile();
-
-   void copyTo(SequentialFile newFileName) throws Exception;
-
-   void setTimedBuffer(TimedBuffer buffer);
-
-   /**
-    * Returns a native File of the file underlying this sequential file.
-    */
-   File getJavaFile();
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFileFactory.java
deleted file mode 100644
index cb47bd9..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFileFactory.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.util.List;
-
-/**
- *
- * A SequentialFileFactory
- */
-public interface SequentialFileFactory
-{
-   SequentialFile createSequentialFile(String fileName, int maxIO);
-
-   /**
-    * Lists files that end with the given extension.
-    * <p>
-    * This method inserts a ".' before the extension.
-    * @param extension
-    * @return
-    * @throws Exception
-    */
-   List<String> listFiles(String extension) throws Exception;
-
-   boolean isSupportsCallbacks();
-
-   /** The SequentialFile will call this method when a disk IO Error happens during the live phase. */
-   void onIOError(Exception exception, String message, SequentialFile file);
-
-   /** used for cases where you need direct buffer outside of the journal context.
-    *  This is because the native layer has a method that can be reused in certain cases like paging */
-   ByteBuffer allocateDirectBuffer(int size);
-
-   /** used for cases where you need direct buffer outside of the journal context.
-    *  This is because the native layer has a method that can be reused in certain cases like paging */
-   void releaseDirectBuffer(ByteBuffer buffer);
-
-   /**
-    * Note: You need to release the buffer if is used for reading operations. You don't need to do
-    * it if using writing operations (AIO Buffer Lister will take of writing operations)
-    * @param size
-    * @return the allocated ByteBuffer
-    */
-   ByteBuffer newBuffer(int size);
-
-   void releaseBuffer(ByteBuffer buffer);
-
-   void activateBuffer(SequentialFile file);
-
-   void deactivateBuffer();
-
-   // To be used in tests only
-   ByteBuffer wrapBuffer(byte[] bytes);
-
-   int getAlignment();
-
-   int calculateBlockSize(int bytes);
-
-   File getDirectory();
-
-   void clearBuffer(ByteBuffer buffer);
-
-   void start();
-
-   void stop();
-
-   /**
-    * Creates the directory if it does not exist yet.
-    */
-   void createDirs() throws Exception;
-
-   void flush();
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFile.java
deleted file mode 100644
index acef8a5..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFile.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.concurrent.Executor;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.asyncio.AsynchronousFile;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
-import org.apache.activemq.artemis.core.asyncio.IOExceptionListener;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-
-public class AIOSequentialFile extends AbstractSequentialFile implements IOExceptionListener
-{
-   private boolean opened = false;
-
-   private final int maxIO;
-
-   private AsynchronousFile aioFile;
-
-   private final BufferCallback bufferCallback;
-
-   /** The pool for Thread pollers */
-   private final Executor pollerExecutor;
-
-   public AIOSequentialFile(final SequentialFileFactory factory,
-                            final int bufferSize,
-                            final long bufferTimeoutMilliseconds,
-                            final File directory,
-                            final String fileName,
-                            final int maxIO,
-                            final BufferCallback bufferCallback,
-                            final Executor writerExecutor,
-                            final Executor pollerExecutor)
-   {
-      super(directory, fileName, factory, writerExecutor);
-      this.maxIO = maxIO;
-      this.bufferCallback = bufferCallback;
-      this.pollerExecutor = pollerExecutor;
-   }
-
-   public boolean isOpen()
-   {
-      return opened;
-   }
-
-   public int getAlignment()
-   {
-      checkOpened();
-
-      return aioFile.getBlockSize();
-   }
-
-   public int calculateBlockStart(final int position)
-   {
-      int alignment = getAlignment();
-
-      int pos = (position / alignment + (position % alignment != 0 ? 1 : 0)) * alignment;
-
-      return pos;
-   }
-
-   public SequentialFile cloneFile()
-   {
-      return new AIOSequentialFile(factory,
-                                   -1,
-                                   -1,
-                                   getFile().getParentFile(),
-                                   getFile().getName(),
-                                   maxIO,
-                                   bufferCallback,
-                                   writerExecutor,
-                                   pollerExecutor);
-   }
-
-   @Override
-   public synchronized void close() throws IOException, InterruptedException, ActiveMQException
-   {
-      if (!opened)
-      {
-         return;
-      }
-
-      super.close();
-
-      opened = false;
-
-      timedBuffer = null;
-
-      aioFile.close();
-      aioFile = null;
-
-      notifyAll();
-   }
-
-   @Override
-   public synchronized void waitForClose() throws Exception
-   {
-      while (isOpen())
-      {
-         wait();
-      }
-   }
-
-   public void fill(final int position, final int size, final byte fillCharacter) throws Exception
-   {
-      checkOpened();
-
-      int fileblockSize = aioFile.getBlockSize();
-
-      int blockSize = fileblockSize;
-
-      if (size % (100 * 1024 * 1024) == 0)
-      {
-         blockSize = 100 * 1024 * 1024;
-      }
-      else if (size % (10 * 1024 * 1024) == 0)
-      {
-         blockSize = 10 * 1024 * 1024;
-      }
-      else if (size % (1024 * 1024) == 0)
-      {
-         blockSize = 1024 * 1024;
-      }
-      else if (size % (10 * 1024) == 0)
-      {
-         blockSize = 10 * 1024;
-      }
-      else
-      {
-         blockSize = fileblockSize;
-      }
-
-      int blocks = size / blockSize;
-
-      if (size % blockSize != 0)
-      {
-         blocks++;
-      }
-
-      int filePosition = position;
-
-      if (position % fileblockSize != 0)
-      {
-         filePosition = (position / fileblockSize + 1) * fileblockSize;
-      }
-
-      aioFile.fill(filePosition, blocks, blockSize, fillCharacter);
-
-      fileSize = aioFile.size();
-   }
-
-   public void open() throws Exception
-   {
-      open(maxIO, true);
-   }
-
-   public synchronized void open(final int maxIO, final boolean useExecutor) throws ActiveMQException
-   {
-      opened = true;
-
-      aioFile = new AsynchronousFileImpl(useExecutor ? writerExecutor : null, pollerExecutor, this);
-
-      try
-      {
-         aioFile.open(getFile().getAbsolutePath(), maxIO);
-      }
-      catch (ActiveMQException e)
-      {
-         factory.onIOError(e, e.getMessage(), this);
-         throw e;
-      }
-
-      position.set(0);
-
-      aioFile.setBufferCallback(bufferCallback);
-
-      fileSize = aioFile.size();
-   }
-
-   public void setBufferCallback(final BufferCallback callback)
-   {
-      aioFile.setBufferCallback(callback);
-   }
-
-   public int read(final ByteBuffer bytes, final IOAsyncTask callback) throws ActiveMQException
-   {
-      int bytesToRead = bytes.limit();
-
-      long positionToRead = position.getAndAdd(bytesToRead);
-
-      bytes.rewind();
-
-      aioFile.read(positionToRead, bytesToRead, bytes, callback);
-
-      return bytesToRead;
-   }
-
-   public int read(final ByteBuffer bytes) throws Exception
-   {
-      SimpleWaitIOCallback waitCompletion = new SimpleWaitIOCallback();
-
-      int bytesRead = read(bytes, waitCompletion);
-
-      waitCompletion.waitCompletion();
-
-      return bytesRead;
-   }
-
-   public void sync()
-   {
-      throw new UnsupportedOperationException("This method is not supported on AIO");
-   }
-
-   public long size() throws Exception
-   {
-      if (aioFile == null)
-      {
-         return getFile().length();
-      }
-      else
-      {
-         return aioFile.size();
-      }
-   }
-
-   @Override
-   public String toString()
-   {
-      return "AIOSequentialFile:" + getFile().getAbsolutePath();
-   }
-
-   // Public methods
-   // -----------------------------------------------------------------------------------------------------
-
-   @Override
-   public void onIOException(Exception code, String message)
-   {
-      factory.onIOError(code, message, this);
-   }
-
-
-   public void writeDirect(final ByteBuffer bytes, final boolean sync) throws Exception
-   {
-      if (sync)
-      {
-         SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
-
-         writeDirect(bytes, true, completion);
-
-         completion.waitCompletion();
-      }
-      else
-      {
-         writeDirect(bytes, false, DummyCallback.getInstance());
-      }
-   }
-
-   /**
-    *
-    * @param sync Not used on AIO
-    *  */
-   public void writeDirect(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback)
-   {
-      final int bytesToWrite = factory.calculateBlockSize(bytes.limit());
-
-      final long positionToWrite = position.getAndAdd(bytesToWrite);
-
-      aioFile.write(positionToWrite, bytesToWrite, bytes, callback);
-   }
-
-   public void writeInternal(final ByteBuffer bytes) throws ActiveMQException
-   {
-      final int bytesToWrite = factory.calculateBlockSize(bytes.limit());
-
-      final long positionToWrite = position.getAndAdd(bytesToWrite);
-
-      aioFile.writeInternal(positionToWrite, bytesToWrite, bytes);
-   }
-
-   // Protected methods
-   // -----------------------------------------------------------------------------------------------------
-
-   @Override
-   protected ByteBuffer newBuffer(int size, int limit)
-   {
-      size = factory.calculateBlockSize(size);
-      limit = factory.calculateBlockSize(limit);
-
-      ByteBuffer buffer = factory.newBuffer(size);
-      buffer.limit(limit);
-      return buffer;
-   }
-
-   // Private methods
-   // -----------------------------------------------------------------------------------------------------
-
-   private void checkOpened()
-   {
-      if (aioFile == null || !opened)
-      {
-         throw new IllegalStateException("File not opened");
-      }
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFileFactory.java
deleted file mode 100644
index 65e6a6f..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFileFactory.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.libaio.Native;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-
-public final class AIOSequentialFileFactory extends AbstractSequentialFileFactory
-{
-   private static final boolean trace = ActiveMQJournalLogger.LOGGER.isTraceEnabled();
-
-   private final ReuseBuffersController buffersControl = new ReuseBuffersController();
-
-   private ExecutorService pollerExecutor;
-
-   // This method exists just to make debug easier.
-   // I could replace log.trace by log.info temporarily while I was debugging
-   // Journal
-   private static void trace(final String message)
-   {
-      ActiveMQJournalLogger.LOGGER.trace(message);
-   }
-
-   public AIOSequentialFileFactory(final File journalDir)
-   {
-      this(journalDir,
-           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
-           JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
-           false,
-           null);
-   }
-
-   public AIOSequentialFileFactory(final File journalDir, final IOCriticalErrorListener listener)
-   {
-      this(journalDir,
-           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
-           JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
-           false,
-           listener);
-   }
-
-   public AIOSequentialFileFactory(final File journalDir,
-                                   final int bufferSize,
-                                   final int bufferTimeout,
-                                   final boolean logRates)
-   {
-      this(journalDir, bufferSize, bufferTimeout, logRates, null);
-   }
-
-   public AIOSequentialFileFactory(final File journalDir,
-                                   final int bufferSize,
-                                   final int bufferTimeout,
-                                   final boolean logRates,
-                                   final IOCriticalErrorListener listener)
-   {
-      super(journalDir, true, bufferSize, bufferTimeout, logRates, listener);
-   }
-
-   public SequentialFile createSequentialFile(final String fileName, final int maxIO)
-   {
-      return new AIOSequentialFile(this,
-                                   bufferSize,
-                                   bufferTimeout,
-                                   journalDir,
-                                   fileName,
-                                   maxIO,
-                                   buffersControl.callback,
-                                   writeExecutor,
-                                   pollerExecutor);
-   }
-
-   public boolean isSupportsCallbacks()
-   {
-      return true;
-   }
-
-   public static boolean isSupported()
-   {
-      return AsynchronousFileImpl.isLoaded();
-   }
-
-   public ByteBuffer allocateDirectBuffer(final int size)
-   {
-
-      int blocks = size / 512;
-      if (size % 512 != 0)
-      {
-         blocks++;
-      }
-
-      // The buffer on AIO has to be a multiple of 512
-      ByteBuffer buffer = AsynchronousFileImpl.newBuffer(blocks * 512);
-
-      buffer.limit(size);
-
-      return buffer;
-   }
-
-   public void releaseDirectBuffer(final ByteBuffer buffer)
-   {
-      Native.destroyBuffer(buffer);
-   }
-
-   public ByteBuffer newBuffer(int size)
-   {
-      if (size % 512 != 0)
-      {
-         size = (size / 512 + 1) * 512;
-      }
-
-      return buffersControl.newBuffer(size);
-   }
-
-   public void clearBuffer(final ByteBuffer directByteBuffer)
-   {
-      AsynchronousFileImpl.clearBuffer(directByteBuffer);
-   }
-
-   public int getAlignment()
-   {
-      return 512;
-   }
-
-   // For tests only
-   public ByteBuffer wrapBuffer(final byte[] bytes)
-   {
-      ByteBuffer newbuffer = newBuffer(bytes.length);
-      newbuffer.put(bytes);
-      return newbuffer;
-   }
-
-   public int calculateBlockSize(final int position)
-   {
-      int alignment = getAlignment();
-
-      int pos = (position / alignment + (position % alignment != 0 ? 1 : 0)) * alignment;
-
-      return pos;
-   }
-
-   /* (non-Javadoc)
-    * @see org.apache.activemq.artemis.core.journal.SequentialFileFactory#releaseBuffer(java.nio.ByteBuffer)
-    */
-   @Override
-   public synchronized void releaseBuffer(final ByteBuffer buffer)
-   {
-      Native.destroyBuffer(buffer);
-   }
-
-   @Override
-   public void start()
-   {
-      super.start();
-
-      pollerExecutor = Executors.newCachedThreadPool(new ActiveMQThreadFactory("ActiveMQ-AIO-poller-pool" + System.identityHashCode(this),
-                                                                              true,
-                                                                              AIOSequentialFileFactory.getThisClassLoader()));
-
-   }
-
-   @Override
-   public void stop()
-   {
-      buffersControl.stop();
-
-      if (pollerExecutor != null)
-      {
-         pollerExecutor.shutdown();
-
-         try
-         {
-            if (!pollerExecutor.awaitTermination(AbstractSequentialFileFactory.EXECUTOR_TIMEOUT, TimeUnit.SECONDS))
-            {
-               ActiveMQJournalLogger.LOGGER.timeoutOnPollerShutdown(new Exception("trace"));
-            }
-         }
-         catch (InterruptedException e)
-         {
-            throw new ActiveMQInterruptedException(e);
-         }
-      }
-
-      super.stop();
-   }
-
-   @Override
-   protected void finalize()
-   {
-      stop();
-   }
-
-   /**
-    * Class that will control buffer-reuse
-    */
-   private class ReuseBuffersController
-   {
-      private volatile long bufferReuseLastTime = System.currentTimeMillis();
-
-      /**
-       * This queue is fed by {@link org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory.ReuseBuffersController.LocalBufferCallback}
-       * which is called directly by NIO or NIO. On the case of the AIO this is almost called by the native layer as
-       * soon as the buffer is not being used any more and ready to be reused or GCed
-       */
-      private final ConcurrentLinkedQueue<ByteBuffer> reuseBuffersQueue = new ConcurrentLinkedQueue<ByteBuffer>();
-
-      private boolean stopped = false;
-
-      final BufferCallback callback = new LocalBufferCallback();
-
-      public ByteBuffer newBuffer(final int size)
-      {
-         // if a new buffer wasn't requested in 10 seconds, we clear the queue
-         // This is being done this way as we don't need another Timeout Thread
-         // just to cleanup this
-         if (bufferSize > 0 && System.currentTimeMillis() - bufferReuseLastTime > 10000)
-         {
-            if (AIOSequentialFileFactory.trace)
-            {
-               AIOSequentialFileFactory.trace("Clearing reuse buffers queue with " + reuseBuffersQueue.size() +
-                                                 " elements");
-            }
-
-            bufferReuseLastTime = System.currentTimeMillis();
-
-            clearPoll();
-         }
-
-         // if a buffer is bigger than the configured-bufferSize, we just create a new
-         // buffer.
-         if (size > bufferSize)
-         {
-            return AsynchronousFileImpl.newBuffer(size);
-         }
-         else
-         {
-            // We need to allocate buffers following the rules of the storage
-            // being used (AIO/NIO)
-            int alignedSize = calculateBlockSize(size);
-
-            // Try getting a buffer from the queue...
-            ByteBuffer buffer = reuseBuffersQueue.poll();
-
-            if (buffer == null)
-            {
-               // if empty create a new one.
-               buffer = AsynchronousFileImpl.newBuffer(bufferSize);
-
-               buffer.limit(alignedSize);
-            }
-            else
-            {
-               clearBuffer(buffer);
-
-               // set the limit of the buffer to the bufferSize being required
-               buffer.limit(alignedSize);
-            }
-
-            buffer.rewind();
-
-            return buffer;
-         }
-      }
-
-      public synchronized void stop()
-      {
-         stopped = true;
-         clearPoll();
-      }
-
-      public synchronized void clearPoll()
-      {
-         ByteBuffer reusedBuffer;
-
-         while ((reusedBuffer = reuseBuffersQueue.poll()) != null)
-         {
-            releaseBuffer(reusedBuffer);
-         }
-      }
-
-      private class LocalBufferCallback implements BufferCallback
-      {
-         public void bufferDone(final ByteBuffer buffer)
-         {
-            synchronized (ReuseBuffersController.this)
-            {
-
-               if (stopped)
-               {
-                  releaseBuffer(buffer);
-               }
-               else
-               {
-                  bufferReuseLastTime = System.currentTimeMillis();
-
-                  // If a buffer has any other than the configured bufferSize, the buffer
-                  // will be just sent to GC
-                  if (buffer.capacity() == bufferSize)
-                  {
-                     reuseBuffersQueue.offer(buffer);
-                  }
-                  else
-                  {
-                     releaseBuffer(buffer);
-                  }
-               }
-            }
-         }
-      }
-   }
-
-   private static ClassLoader getThisClassLoader()
-   {
-      return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
-      {
-         public ClassLoader run()
-         {
-            return AIOSequentialFileFactory.class.getClassLoader();
-         }
-      });
-
-   }
-
-   @Override
-   public String toString()
-   {
-      return AIOSequentialFileFactory.class.getSimpleName() + "(buffersControl.stopped=" + buffersControl.stopped +
-         "):" + super.toString();
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java
index e21b046..b36a0c4 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java
@@ -24,8 +24,8 @@ import java.util.Set;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
 import org.apache.activemq.artemis.api.core.Pair;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecord;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalInternalRecord;
@@ -87,7 +87,7 @@ public abstract class AbstractJournalUpdateTask implements JournalReaderCallback
                                                  final List<Pair<String, String>> renames) throws Exception
    {
 
-      SequentialFile controlFile = fileFactory.createSequentialFile(AbstractJournalUpdateTask.FILE_COMPACT_CONTROL, 1);
+      SequentialFile controlFile = fileFactory.createSequentialFile(AbstractJournalUpdateTask.FILE_COMPACT_CONTROL);
 
       try
       {
@@ -182,7 +182,7 @@ public abstract class AbstractJournalUpdateTask implements JournalReaderCallback
          // To Fix the size of the file
          writingChannel.writerIndex(writingChannel.capacity());
 
-         sequentialFile.writeInternal(writingChannel.toByteBuffer());
+         sequentialFile.writeDirect(writingChannel.toByteBuffer(), true);
          sequentialFile.close();
          newDataFiles.add(currentFile);
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFile.java
deleted file mode 100644
index a4eed58..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFile.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
-import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.journal.ActiveMQJournalBundle;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-public abstract class AbstractSequentialFile implements SequentialFile
-{
-
-   private File file;
-
-   protected final File directory;
-
-   protected final SequentialFileFactory factory;
-
-   protected long fileSize = 0;
-
-   protected final AtomicLong position = new AtomicLong(0);
-
-   protected TimedBuffer timedBuffer;
-
-   /**
-    * Instead of having AIOSequentialFile implementing the Observer, I have done it on an inner class.
-    * This is the class returned to the factory when the file is being activated.
-    */
-   protected final TimedBufferObserver timedBufferObserver = new LocalBufferObserver();
-
-   /**
-    * Used for asynchronous writes
-    */
-   protected final Executor writerExecutor;
-
-   /**
-    * @param file
-    * @param directory
-    */
-   public AbstractSequentialFile(final File directory,
-                                 final String file,
-                                 final SequentialFileFactory factory,
-                                 final Executor writerExecutor)
-   {
-      super();
-      this.file = new File(directory, file);
-      this.directory = directory;
-      this.factory = factory;
-      this.writerExecutor = writerExecutor;
-   }
-
-   // Public --------------------------------------------------------
-
-   public final boolean exists()
-   {
-      return file.exists();
-   }
-
-   public final String getFileName()
-   {
-      return file.getName();
-   }
-
-   public final void delete() throws IOException, InterruptedException, ActiveMQException
-   {
-      if (isOpen())
-      {
-         close();
-      }
-
-      if (file.exists() && !file.delete())
-      {
-         ActiveMQJournalLogger.LOGGER.errorDeletingFile(this);
-      }
-   }
-
-   public void copyTo(SequentialFile newFileName) throws Exception
-   {
-      try
-      {
-         ActiveMQJournalLogger.LOGGER.debug("Copying " + this + " as " + newFileName);
-         if (!newFileName.isOpen())
-         {
-            newFileName.open();
-         }
-
-         if (!isOpen())
-         {
-            this.open();
-         }
-
-
-         ByteBuffer buffer = ByteBuffer.allocate(10 * 1024);
-
-         for (;;)
-         {
-            buffer.rewind();
-            int size = this.read(buffer);
-            newFileName.writeDirect(buffer, false);
-            if (size < 10 * 1024)
-            {
-               break;
-            }
-         }
-         newFileName.close();
-         this.close();
-      }
-      catch (IOException e)
-      {
-         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-         throw e;
-      }
-   }
-
-   /**
-    * @throws IOException only declare exception due to signature. Sub-class needs it.
-    */
-   @Override
-   public void position(final long pos) throws IOException
-   {
-      position.set(pos);
-   }
-
-   public long position()
-   {
-      return position.get();
-   }
-
-   public final void renameTo(final String newFileName) throws IOException, InterruptedException,
-      ActiveMQException
-   {
-      try
-      {
-         close();
-      }
-      catch (IOException e)
-      {
-         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-         throw e;
-      }
-
-      File newFile = new File(directory + "/" + newFileName);
-
-      if (!file.equals(newFile))
-      {
-         if (!file.renameTo(newFile))
-         {
-            throw ActiveMQJournalBundle.BUNDLE.ioRenameFileError(file.getName(), newFileName);
-         }
-         file = newFile;
-      }
-   }
-
-   /**
-    * @throws IOException      we declare throwing IOException because sub-classes need to do it
-    * @throws ActiveMQException
-    */
-   public synchronized void close() throws IOException, InterruptedException, ActiveMQException
-   {
-      final CountDownLatch donelatch = new CountDownLatch(1);
-
-      if (writerExecutor != null)
-      {
-         writerExecutor.execute(new Runnable()
-         {
-            public void run()
-            {
-               donelatch.countDown();
-            }
-         });
-
-         while (!donelatch.await(60, TimeUnit.SECONDS))
-         {
-            ActiveMQJournalLogger.LOGGER.couldNotCompleteTask(new Exception("trace"), file.getName());
-         }
-      }
-   }
-
-   public final boolean fits(final int size)
-   {
-      if (timedBuffer == null)
-      {
-         return position.get() + size <= fileSize;
-      }
-      else
-      {
-         return timedBuffer.checkSize(size);
-      }
-   }
-
-   public void setTimedBuffer(final TimedBuffer buffer)
-   {
-      if (timedBuffer != null)
-      {
-         timedBuffer.setObserver(null);
-      }
-
-      timedBuffer = buffer;
-
-      if (buffer != null)
-      {
-         buffer.setObserver(timedBufferObserver);
-      }
-
-   }
-
-   public void write(final ActiveMQBuffer bytes, final boolean sync, final IOAsyncTask callback) throws IOException
-   {
-      if (timedBuffer != null)
-      {
-         bytes.setIndex(0, bytes.capacity());
-         timedBuffer.addBytes(bytes, sync, callback);
-      }
-      else
-      {
-         ByteBuffer buffer = factory.newBuffer(bytes.capacity());
-         buffer.put(bytes.toByteBuffer().array());
-         buffer.rewind();
-         writeDirect(buffer, sync, callback);
-      }
-   }
-
-   public void write(final ActiveMQBuffer bytes, final boolean sync) throws IOException, InterruptedException,
-      ActiveMQException
-   {
-      if (sync)
-      {
-         SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
-
-         write(bytes, true, completion);
-
-         completion.waitCompletion();
-      }
-      else
-      {
-         write(bytes, false, DummyCallback.getInstance());
-      }
-   }
-
-   public void write(final EncodingSupport bytes, final boolean sync, final IOAsyncTask callback)
-   {
-      if (timedBuffer != null)
-      {
-         timedBuffer.addBytes(bytes, sync, callback);
-      }
-      else
-      {
-         ByteBuffer buffer = factory.newBuffer(bytes.getEncodeSize());
-
-         // If not using the TimedBuffer, a final copy is necessary
-         // Because AIO will need a specific Buffer
-         // And NIO will also need a whole buffer to perform the write
-
-         ActiveMQBuffer outBuffer = ActiveMQBuffers.wrappedBuffer(buffer);
-         bytes.encode(outBuffer);
-         buffer.rewind();
-         writeDirect(buffer, sync, callback);
-      }
-   }
-
-   public void write(final EncodingSupport bytes, final boolean sync) throws InterruptedException, ActiveMQException
-   {
-      if (sync)
-      {
-         SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
-
-         write(bytes, true, completion);
-
-         completion.waitCompletion();
-      }
-      else
-      {
-         write(bytes, false, DummyCallback.getInstance());
-      }
-   }
-
-   protected File getFile()
-   {
-      return file;
-   }
-
-   private static final class DelegateCallback implements IOAsyncTask
-   {
-      final List<IOAsyncTask> delegates;
-
-      private DelegateCallback(final List<IOAsyncTask> delegates)
-      {
-         this.delegates = delegates;
-      }
-
-      public void done()
-      {
-         for (IOAsyncTask callback : delegates)
-         {
-            try
-            {
-               callback.done();
-            }
-            catch (Throwable e)
-            {
-               ActiveMQJournalLogger.LOGGER.errorCompletingCallback(e);
-            }
-         }
-      }
-
-      public void onError(final int errorCode, final String errorMessage)
-      {
-         for (IOAsyncTask callback : delegates)
-         {
-            try
-            {
-               callback.onError(errorCode, errorMessage);
-            }
-            catch (Throwable e)
-            {
-               ActiveMQJournalLogger.LOGGER.errorCallingErrorCallback(e);
-            }
-         }
-      }
-   }
-
-   protected ByteBuffer newBuffer(int size, int limit)
-   {
-      size = factory.calculateBlockSize(size);
-      limit = factory.calculateBlockSize(limit);
-
-      ByteBuffer buffer = factory.newBuffer(size);
-      buffer.limit(limit);
-      return buffer;
-   }
-
-   protected class LocalBufferObserver implements TimedBufferObserver
-   {
-      public void flushBuffer(final ByteBuffer buffer, final boolean requestedSync, final List<IOAsyncTask> callbacks)
-      {
-         buffer.flip();
-
-         if (buffer.limit() == 0)
-         {
-            factory.releaseBuffer(buffer);
-         }
-         else
-         {
-            writeDirect(buffer, requestedSync, new DelegateCallback(callbacks));
-         }
-      }
-
-      public ByteBuffer newBuffer(final int size, final int limit)
-      {
-         return AbstractSequentialFile.this.newBuffer(size, limit);
-      }
-
-      public int getRemainingBytes()
-      {
-         if (fileSize - position.get() > Integer.MAX_VALUE)
-         {
-            return Integer.MAX_VALUE;
-         }
-         else
-         {
-            return (int)(fileSize - position.get());
-         }
-      }
-
-      @Override
-      public String toString()
-      {
-         return "TimedBufferObserver on file (" + getFile().getName() + ")";
-      }
-
-   }
-
-   @Override
-   public File getJavaFile()
-   {
-      return getFile().getAbsoluteFile();
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFileFactory.java
deleted file mode 100644
index ec0ab4d..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFileFactory.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-
-/**
- * An abstract SequentialFileFactory containing basic functionality for both AIO and NIO SequentialFactories
- */
-abstract class AbstractSequentialFileFactory implements SequentialFileFactory
-{
-
-   // Timeout used to wait executors to shutdown
-   protected static final int EXECUTOR_TIMEOUT = 60;
-
-   protected final File journalDir;
-
-   protected final TimedBuffer timedBuffer;
-
-   protected final int bufferSize;
-
-   protected final long bufferTimeout;
-
-   private final IOCriticalErrorListener critialErrorListener;
-
-   /**
-    * Asynchronous writes need to be done at another executor.
-    * This needs to be done at NIO, or else we would have the callers thread blocking for the return.
-    * At AIO this is necessary as context switches on writes would fire flushes at the kernel.
-    *  */
-   protected ExecutorService writeExecutor;
-
-   AbstractSequentialFileFactory(final File journalDir,
-                                        final boolean buffered,
-                                        final int bufferSize,
-                                        final int bufferTimeout,
-                                        final boolean logRates,
-                                        final IOCriticalErrorListener criticalErrorListener)
-   {
-      this.journalDir = journalDir;
-
-      if (buffered)
-      {
-         timedBuffer = new TimedBuffer(bufferSize, bufferTimeout, logRates);
-      }
-      else
-      {
-         timedBuffer = null;
-      }
-      this.bufferSize = bufferSize;
-      this.bufferTimeout = bufferTimeout;
-      this.critialErrorListener = criticalErrorListener;
-   }
-
-   public void stop()
-   {
-      if (timedBuffer != null)
-      {
-         timedBuffer.stop();
-      }
-
-      if (isSupportsCallbacks() && writeExecutor != null)
-      {
-         writeExecutor.shutdown();
-
-         try
-         {
-            if (!writeExecutor.awaitTermination(AbstractSequentialFileFactory.EXECUTOR_TIMEOUT, TimeUnit.SECONDS))
-            {
-               ActiveMQJournalLogger.LOGGER.timeoutOnWriterShutdown(new Exception("trace"));
-            }
-         }
-         catch (InterruptedException e)
-         {
-            throw new ActiveMQInterruptedException(e);
-         }
-      }
-   }
-
-   @Override
-   public File getDirectory()
-   {
-      return journalDir;
-   }
-
-   public void start()
-   {
-      if (timedBuffer != null)
-      {
-         timedBuffer.start();
-      }
-
-      if (isSupportsCallbacks())
-      {
-         writeExecutor = Executors.newSingleThreadExecutor(new ActiveMQThreadFactory("ActiveMQ-Asynchronous-Persistent-Writes" + System.identityHashCode(this),
-                                                                                    true,
-                                                                                    AbstractSequentialFileFactory.getThisClassLoader()));
-      }
-
-   }
-
-   @Override
-   public void onIOError(Exception exception, String message, SequentialFile file)
-   {
-      if (critialErrorListener != null)
-      {
-         critialErrorListener.onIOException(exception, message, file);
-      }
-   }
-
-   @Override
-   public void activateBuffer(final SequentialFile file)
-   {
-      if (timedBuffer != null)
-      {
-         file.setTimedBuffer(timedBuffer);
-      }
-   }
-
-   public void flush()
-   {
-      if (timedBuffer != null)
-      {
-         timedBuffer.flush();
-      }
-   }
-
-   public void deactivateBuffer()
-   {
-      if (timedBuffer != null)
-      {
-         // When moving to a new file, we need to make sure any pending buffer will be transferred to the buffer
-         timedBuffer.flush();
-         timedBuffer.setObserver(null);
-      }
-   }
-
-   public void releaseBuffer(final ByteBuffer buffer)
-   {
-   }
-
-   /**
-    * Create the directory if it doesn't exist yet
-    */
-   public void createDirs() throws Exception
-   {
-      boolean ok = journalDir.mkdirs();
-      if (!ok)
-      {
-         throw new IOException("Failed to create directory " + journalDir);
-      }
-   }
-
-   public List<String> listFiles(final String extension) throws Exception
-   {
-      FilenameFilter fnf = new FilenameFilter()
-      {
-         public boolean accept(final File file, final String name)
-         {
-            return name.endsWith("." + extension);
-         }
-      };
-
-      String[] fileNames = journalDir.list(fnf);
-
-      if (fileNames == null)
-      {
-         return Collections.EMPTY_LIST;
-      }
-
-      return Arrays.asList(fileNames);
-   }
-
-   private static ClassLoader getThisClassLoader()
-   {
-      return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
-      {
-         public ClassLoader run()
-         {
-            return AbstractSequentialFileFactory.class.getClassLoader();
-         }
-      });
-
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/DummyCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/DummyCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/DummyCallback.java
deleted file mode 100644
index 9c4c3d6..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/DummyCallback.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-class DummyCallback extends SyncIOCompletion
-{
-   private static final DummyCallback instance = new DummyCallback();
-
-   public static DummyCallback getInstance()
-   {
-      return DummyCallback.instance;
-   }
-
-   public void done()
-   {
-   }
-
-   public void onError(final int errorCode, final String errorMessage)
-   {
-      ActiveMQJournalLogger.LOGGER.errorWritingData(new Exception(errorMessage), errorMessage, errorCode);
-   }
-
-   @Override
-   public void waitCompletion() throws Exception
-   {
-   }
-
-   @Override
-   public void storeLineUp()
-   {
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java
index a41e72f..5a0f11f 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java
@@ -32,7 +32,7 @@ import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
 import org.apache.activemq.artemis.core.journal.LoaderCallback;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecord;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecordTX;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java
index d6a856a..1ba8f0b 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java
@@ -17,6 +17,7 @@
 package org.apache.activemq.artemis.core.journal.impl;
 
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.core.io.DummyCallback;
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
 import org.apache.activemq.artemis.core.journal.IOCompletion;
 import org.apache.activemq.artemis.core.journal.Journal;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java
index 5b0a1b8..1f657a2 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java
@@ -28,8 +28,8 @@ import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecord;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecordTX;
@@ -64,7 +64,7 @@ public class JournalCompactor extends AbstractJournalUpdateTask implements Journ
                                                 final List<String> newFiles,
                                                 final List<Pair<String, String>> renameFile) throws Exception
    {
-      SequentialFile controlFile = fileFactory.createSequentialFile(AbstractJournalUpdateTask.FILE_COMPACT_CONTROL, 1);
+      SequentialFile controlFile = fileFactory.createSequentialFile(AbstractJournalUpdateTask.FILE_COMPACT_CONTROL);
 
       if (controlFile.exists())
       {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java
index e3b1624..dcfc1a2 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java
@@ -16,7 +16,7 @@
  */
 package org.apache.activemq.artemis.core.journal.impl;
 
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 
 public interface JournalFile
 {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java
index 4438a96..7e96575 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java
@@ -21,7 +21,7 @@ import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 
 public class JournalFileImpl implements JournalFile
 {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java
index 052dc25..268a23d 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java
@@ -31,8 +31,8 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
 
 /**
@@ -662,13 +662,13 @@ public class JournalFilesRepository
 
       String tmpFileName = fileName + ".tmp";
 
-      SequentialFile sequentialFile = fileFactory.createSequentialFile(tmpFileName, maxAIO);
+      SequentialFile sequentialFile = fileFactory.createSequentialFile(tmpFileName);
 
       sequentialFile.open(1, false);
 
       if (init)
       {
-         sequentialFile.fill(0, fileSize, JournalImpl.FILL_CHARACTER);
+         sequentialFile.fill(fileSize);
 
          JournalImpl.initFileHeader(fileFactory, sequentialFile, userVersion, fileID);
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java
index 6f411eb..068e697 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java
@@ -46,15 +46,15 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
 import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.journal.IOCompletion;
 import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
 import org.apache.activemq.artemis.core.journal.LoaderCallback;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.TestableJournal;
 import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
@@ -293,7 +293,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
 
       final CountDownLatch latch = new CountDownLatch(numIts * 2);
 
-      class MyIOAsyncTask implements IOCompletion
+      class MyAIOCallback implements IOCompletion
       {
          public void done()
          {
@@ -310,7 +310,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
          }
       }
 
-      final MyIOAsyncTask task = new MyIOAsyncTask();
+      final MyAIOCallback task = new MyAIOCallback();
 
       final int recordSize = 1024;
 
@@ -373,11 +373,11 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
 
       for (String fileName : fileNames)
       {
-         SequentialFile file = fileFactory.createSequentialFile(fileName, filesRepository.getMaxAIO());
+         SequentialFile file = fileFactory.createSequentialFile(fileName);
 
          if (file.size() >= SIZE_HEADER)
          {
-            file.open(1, false);
+            file.open();
 
             try
             {
@@ -2776,11 +2776,11 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
                                     final boolean completeTransaction,
                                     final boolean sync,
                                     final JournalTransaction tx,
-                                    final IOAsyncTask parameterCallback) throws Exception
+                                    final IOCallback parameterCallback) throws Exception
    {
       checkJournalIsLoaded();
 
-      final IOAsyncTask callback;
+      final IOCallback callback;
 
       final int size = encoder.getEncodeSize();
 
@@ -2896,7 +2896,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
       {
          for (String dataFile : dataFiles)
          {
-            SequentialFile file = fileFactory.createSequentialFile(dataFile, 1);
+            SequentialFile file = fileFactory.createSequentialFile(dataFile);
             if (file.exists())
             {
                file.delete();
@@ -2905,7 +2905,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
 
          for (String newFile : newFiles)
          {
-            SequentialFile file = fileFactory.createSequentialFile(newFile, 1);
+            SequentialFile file = fileFactory.createSequentialFile(newFile);
             if (file.exists())
             {
                final String originalName = file.getFileName();
@@ -2916,8 +2916,8 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
 
          for (Pair<String, String> rename : renames)
          {
-            SequentialFile fileTmp = fileFactory.createSequentialFile(rename.getA(), 1);
-            SequentialFile fileTo = fileFactory.createSequentialFile(rename.getB(), 1);
+            SequentialFile fileTmp = fileFactory.createSequentialFile(rename.getA());
+            SequentialFile fileTo = fileFactory.createSequentialFile(rename.getB());
             // We should do the rename only if the tmp file still exist, or else we could
             // delete a valid file depending on where the crash occurred during the control file delete
             if (fileTmp.exists())
@@ -2951,7 +2951,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
          for (String fileToDelete : leftFiles)
          {
             ActiveMQJournalLogger.LOGGER.deletingOrphanedFile(fileToDelete);
-            SequentialFile file = fileFactory.createSequentialFile(fileToDelete, 1);
+            SequentialFile file = fileFactory.createSequentialFile(fileToDelete);
             file.delete();
          }
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFile.java
deleted file mode 100644
index 0dac7f2..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFile.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
-import org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.journal.ActiveMQJournalBundle;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-public final class NIOSequentialFile extends AbstractSequentialFile
-{
-   private FileChannel channel;
-
-   private RandomAccessFile rfile;
-
-   /**
-    * The write semaphore here is only used when writing asynchronously
-    */
-   private Semaphore maxIOSemaphore;
-
-   private final int defaultMaxIO;
-
-   private int maxIO;
-
-   public NIOSequentialFile(final SequentialFileFactory factory,
-                            final File directory,
-                            final String file,
-                            final int maxIO,
-                            final Executor writerExecutor)
-   {
-      super(directory, file, factory, writerExecutor);
-      defaultMaxIO = maxIO;
-   }
-
-   public int getAlignment()
-   {
-      return 1;
-   }
-
-   public int calculateBlockStart(final int position)
-   {
-      return position;
-   }
-
-   public synchronized boolean isOpen()
-   {
-      return channel != null;
-   }
-
-   /**
-    * this.maxIO represents the default maxIO.
-    * Some operations while initializing files on the journal may require a different maxIO
-    */
-   public synchronized void open() throws IOException
-   {
-      open(defaultMaxIO, true);
-   }
-
-   public void open(final int maxIO, final boolean useExecutor) throws IOException
-   {
-      try
-      {
-         rfile = new RandomAccessFile(getFile(), "rw");
-
-         channel = rfile.getChannel();
-
-         fileSize = channel.size();
-      }
-      catch (IOException e)
-      {
-         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-         throw e;
-      }
-
-      if (writerExecutor != null && useExecutor)
-      {
-         maxIOSemaphore = new Semaphore(maxIO);
-         this.maxIO = maxIO;
-      }
-   }
-
-   public void fill(final int position, final int size, final byte fillCharacter) throws IOException
-   {
-      ByteBuffer bb = ByteBuffer.allocate(size);
-
-      for (int i = 0; i < size; i++)
-      {
-         bb.put(fillCharacter);
-      }
-
-      bb.flip();
-
-      try
-      {
-         channel.position(position);
-         channel.write(bb);
-         channel.force(false);
-         channel.position(0);
-      }
-      catch (IOException e)
-      {
-         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-         throw e;
-      }
-
-      fileSize = channel.size();
-   }
-
-   public synchronized void waitForClose() throws InterruptedException
-   {
-      while (isOpen())
-      {
-         wait();
-      }
-   }
-
-   @Override
-   public synchronized void close() throws IOException, InterruptedException, ActiveMQException
-   {
-      super.close();
-
-      if (maxIOSemaphore != null)
-      {
-         while (!maxIOSemaphore.tryAcquire(maxIO, 60, TimeUnit.SECONDS))
-         {
-            ActiveMQJournalLogger.LOGGER.errorClosingFile(getFileName());
-         }
-      }
-
-      maxIOSemaphore = null;
-      try
-      {
-         if (channel != null)
-         {
-            channel.close();
-         }
-
-         if (rfile != null)
-         {
-            rfile.close();
-         }
-      }
-      catch (IOException e)
-      {
-         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-         throw e;
-      }
-      channel = null;
-
-      rfile = null;
-
-      notifyAll();
-   }
-
-   public int read(final ByteBuffer bytes) throws Exception
-   {
-      return read(bytes, null);
-   }
-
-   public synchronized int read(final ByteBuffer bytes, final IOAsyncTask callback) throws IOException,
-      ActiveMQIllegalStateException
-   {
-      try
-      {
-         if (channel == null)
-         {
-            throw new ActiveMQIllegalStateException("File " + this.getFileName() + " has a null channel");
-         }
-         int bytesRead = channel.read(bytes);
-
-         if (callback != null)
-         {
-            callback.done();
-         }
-
-         bytes.flip();
-
-         return bytesRead;
-      }
-      catch (IOException e)
-      {
-         if (callback != null)
-         {
-            callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getLocalizedMessage());
-         }
-
-         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-
-         throw e;
-      }
-   }
-
-   public void sync() throws IOException
-   {
-      if (channel != null)
-      {
-         try
-         {
-            channel.force(false);
-         }
-         catch (IOException e)
-         {
-            factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-            throw e;
-         }
-      }
-   }
-
-   public long size() throws IOException
-   {
-      if (channel == null)
-      {
-         return getFile().length();
-      }
-
-      try
-      {
-         return channel.size();
-      }
-      catch (IOException e)
-      {
-         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-         throw e;
-      }
-   }
-
-   @Override
-   public void position(final long pos) throws IOException
-   {
-      try
-      {
-         super.position(pos);
-         channel.position(pos);
-      }
-      catch (IOException e)
-      {
-         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-         throw e;
-      }
-   }
-
-   @Override
-   public String toString()
-   {
-      return "NIOSequentialFile " + getFile();
-   }
-
-   public SequentialFile cloneFile()
-   {
-      return new NIOSequentialFile(factory, directory, getFileName(), maxIO, writerExecutor);
-   }
-
-   public void writeDirect(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback)
-   {
-      if (callback == null)
-      {
-         throw new NullPointerException("callback parameter need to be set");
-      }
-
-      try
-      {
-         internalWrite(bytes, sync, callback);
-      }
-      catch (Exception e)
-      {
-         callback.onError(ActiveMQExceptionType.GENERIC_EXCEPTION.getCode(), e.getMessage());
-      }
-   }
-
-   public void writeDirect(final ByteBuffer bytes, final boolean sync) throws Exception
-   {
-      internalWrite(bytes, sync, null);
-   }
-
-   public void writeInternal(final ByteBuffer bytes) throws Exception
-   {
-      internalWrite(bytes, true, null);
-   }
-
-   @Override
-   protected ByteBuffer newBuffer(int size, final int limit)
-   {
-      // For NIO, we don't need to allocate a buffer the entire size of the timed buffer, unlike AIO
-
-      size = limit;
-
-      return super.newBuffer(size, limit);
-   }
-
-   private void internalWrite(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback) throws IOException, ActiveMQIOErrorException, InterruptedException
-   {
-      if (!isOpen())
-      {
-         if (callback != null)
-         {
-            callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), "File not opened");
-         }
-         else
-         {
-            throw ActiveMQJournalBundle.BUNDLE.fileNotOpened();
-         }
-         return;
-      }
-
-      position.addAndGet(bytes.limit());
-
-      if (maxIOSemaphore == null || callback == null)
-      {
-         // if maxIOSemaphore == null, that means we are not using executors and the writes are synchronous
-         try
-         {
-            doInternalWrite(bytes, sync, callback);
-         }
-         catch (IOException e)
-         {
-            factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-         }
-      }
-      else
-      {
-         // This is a flow control on writing, just like maxAIO on libaio
-         maxIOSemaphore.acquire();
-
-         writerExecutor.execute(new Runnable()
-         {
-            public void run()
-            {
-               try
-               {
-                  try
-                  {
-                     doInternalWrite(bytes, sync, callback);
-                  }
-                  catch (IOException e)
-                  {
-                     ActiveMQJournalLogger.LOGGER.errorSubmittingWrite(e);
-                     factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), NIOSequentialFile.this);
-                     callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getMessage());
-                  }
-                  catch (Throwable e)
-                  {
-                     ActiveMQJournalLogger.LOGGER.errorSubmittingWrite(e);
-                     callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getMessage());
-                  }
-               }
-               finally
-               {
-                  maxIOSemaphore.release();
-               }
-            }
-         });
-      }
-   }
-
-   /**
-    * @param bytes
-    * @param sync
-    * @param callback
-    * @throws IOException
-    * @throws Exception
-    */
-   private void doInternalWrite(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback) throws IOException
-   {
-      channel.write(bytes);
-
-      if (sync)
-      {
-         sync();
-      }
-
-      if (callback != null)
-      {
-         callback.done();
-      }
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFileFactory.java
deleted file mode 100644
index e471928..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFileFactory.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import java.io.File;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-
-public class NIOSequentialFileFactory extends AbstractSequentialFileFactory
-{
-   public NIOSequentialFileFactory(final File journalDir)
-   {
-      this(journalDir, null);
-   }
-
-   public NIOSequentialFileFactory(final File journalDir, final IOCriticalErrorListener listener)
-   {
-      this(journalDir,
-           false,
-           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO,
-           JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO,
-           false,
-           listener);
-   }
-
-   public NIOSequentialFileFactory(final File journalDir, final boolean buffered)
-   {
-      this(journalDir, buffered, null);
-   }
-
-   public NIOSequentialFileFactory(final File journalDir,
-                                   final boolean buffered,
-                                   final IOCriticalErrorListener listener)
-   {
-      this(journalDir,
-           buffered,
-           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO,
-           JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO,
-           false,
-           listener);
-   }
-
-   public NIOSequentialFileFactory(final File journalDir,
-                                   final boolean buffered,
-                                   final int bufferSize,
-                                   final int bufferTimeout,
-                                   final boolean logRates)
-   {
-      this(journalDir, buffered, bufferSize, bufferTimeout, logRates, null);
-   }
-
-   public NIOSequentialFileFactory(final File journalDir,
-                                   final boolean buffered,
-                                   final int bufferSize,
-                                   final int bufferTimeout,
-                                   final boolean logRates,
-                                   final IOCriticalErrorListener listener)
-   {
-      super(journalDir, buffered, bufferSize, bufferTimeout, logRates, listener);
-   }
-
-   public SequentialFile createSequentialFile(final String fileName, int maxIO)
-   {
-      if (maxIO < 1)
-      {
-         // A single threaded IO
-         maxIO = 1;
-      }
-
-      return new NIOSequentialFile(this, journalDir, fileName, maxIO, writeExecutor);
-   }
-
-   public boolean isSupportsCallbacks()
-   {
-      return timedBuffer != null;
-   }
-
-
-   public ByteBuffer allocateDirectBuffer(final int size)
-   {
-      // Using direct buffer, as described on https://jira.jboss.org/browse/HORNETQ-467
-      ByteBuffer buffer2 = null;
-      try
-      {
-         buffer2 = ByteBuffer.allocateDirect(size);
-      }
-      catch (OutOfMemoryError error)
-      {
-         // This is a workaround for the way the JDK will deal with native buffers.
-         // the main portion is outside of the VM heap
-         // and the JDK will not have any reference about it to take GC into account
-         // so we force a GC and try again.
-         WeakReference<Object> obj = new WeakReference<Object>(new Object());
-         try
-         {
-            long timeout = System.currentTimeMillis() + 5000;
-            while (System.currentTimeMillis() > timeout && obj.get() != null)
-            {
-               System.gc();
-               Thread.sleep(100);
-            }
-         }
-         catch (InterruptedException e)
-         {
-         }
-
-         buffer2 = ByteBuffer.allocateDirect(size);
-
-      }
-      return buffer2;
-   }
-
-   public void releaseDirectBuffer(ByteBuffer buffer)
-   {
-      // nothing we can do on this case. we can just have good faith on GC
-   }
-
-   public ByteBuffer newBuffer(final int size)
-   {
-      return ByteBuffer.allocate(size);
-   }
-
-   public void clearBuffer(final ByteBuffer buffer)
-   {
-      final int limit = buffer.limit();
-      buffer.rewind();
-
-      for (int i = 0; i < limit; i++)
-      {
-         buffer.put((byte)0);
-      }
-
-      buffer.rewind();
-   }
-
-   public ByteBuffer wrapBuffer(final byte[] bytes)
-   {
-      return ByteBuffer.wrap(bytes);
-   }
-
-   public int getAlignment()
-   {
-      return 1;
-   }
-
-   public int calculateBlockSize(final int bytes)
-   {
-      return bytes;
-   }
-
-}


[3/9] activemq-artemis git commit: ARTEMIS-163 First pass on the native AIO refactoring

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
index d245985..fcdff05 100644
--- a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
+++ b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
@@ -36,6 +36,7 @@ import org.apache.activemq.artemis.api.core.BaseInterceptor;
 import org.apache.activemq.artemis.api.core.Interceptor;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.api.core.management.ManagementHelper;
 import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQConsumer;
 import org.apache.activemq.artemis.core.server.management.ManagementService;
@@ -62,7 +63,6 @@ import org.apache.activemq.command.TransactionId;
 import org.apache.activemq.command.TransactionInfo;
 import org.apache.activemq.command.WireFormatInfo;
 import org.apache.activemq.command.XATransactionId;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQConnectionContext;
 import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQPersistenceAdapter;
 import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQProducerBrokerExchange;
@@ -261,7 +261,7 @@ public class OpenWireProtocolManager implements ProtocolManager<Interceptor>, No
    public void sendReply(final OpenWireConnection connection,
                          final Command command)
    {
-      server.getStorageManager().afterCompleteOperations(new IOAsyncTask()
+      server.getStorageManager().afterCompleteOperations(new IOCallback()
       {
          public void onError(final int errorCode, final String errorMessage)
          {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
index a4e8ea5..b3d926c 100644
--- a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
+++ b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
@@ -33,7 +33,7 @@ import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
 import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
 import org.apache.activemq.artemis.api.core.management.ManagementHelper;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.postoffice.BindingType;
 import org.apache.activemq.artemis.core.remoting.impl.netty.NettyServerConnection;
 import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
@@ -357,7 +357,7 @@ class StompProtocolManager implements ProtocolManager<StompFrameInterceptor>, No
 
    public void sendReply(final StompConnection connection, final StompFrame frame)
    {
-      server.getStorageManager().afterCompleteOperations(new IOAsyncTask()
+      server.getStorageManager().afterCompleteOperations(new IOCallback()
       {
          public void onError(final int errorCode, final String errorMessage)
          {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
index 8efeabb..c1b767a 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
@@ -41,7 +41,7 @@ import org.apache.activemq.artemis.core.config.ha.SharedStoreMasterPolicyConfigu
 import org.apache.activemq.artemis.core.config.ha.SharedStoreSlavePolicyConfiguration;
 import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
 import org.apache.activemq.artemis.core.config.impl.Validators;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
 import org.apache.activemq.artemis.core.security.Role;
 import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
index ee3bb86..8e06cde 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
@@ -26,7 +26,7 @@ import org.apache.activemq.artemis.core.settings.HierarchicalRepositoryChangeLis
  * <PRE>
  *
  * +--------------+      1  +----------------+       N +--------------+       N +--------+       1 +-------------------+
- * | {@link org.apache.activemq.artemis.core.postoffice.PostOffice} |-------&gt; |{@link PagingManager}|-------&gt; |{@link PagingStore} | ------&gt; | {@link org.apache.activemq.artemis.core.paging.impl.Page}  | ------&gt; | {@link org.apache.activemq.artemis.core.journal.SequentialFile} |
+ * | {@link org.apache.activemq.artemis.core.postoffice.PostOffice} |-------&gt; |{@link PagingManager}|-------&gt; |{@link PagingStore} | ------&gt; | {@link org.apache.activemq.artemis.core.paging.impl.Page}  | ------&gt; | {@link SequentialFile} |
  * +--------------+         +----------------+         +--------------+         +--------+         +-------------------+
  *                                                              |                  1 ^
  *                                                              |                    |

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
index 3b74e45..b0129e7 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
@@ -158,7 +158,7 @@ public interface PagingStore extends ActiveMQComponent
    /**
     * Sends the pages with given IDs to the {@link ReplicationManager}.
     * <p>
-    * Sending is done here to avoid exposing the internal {@link org.apache.activemq.artemis.core.journal.SequentialFile}s.
+    * Sending is done here to avoid exposing the internal {@link SequentialFile}s.
     *
     * @param replicator
     * @param pageIds

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
index f83966d..0818034 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
@@ -19,7 +19,7 @@ package org.apache.activemq.artemis.core.paging;
 import java.util.List;
 
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
 import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java
index 39324da..e98da75 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java
@@ -32,8 +32,8 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
 import org.apache.activemq.artemis.core.paging.PagingStore;
@@ -521,7 +521,7 @@ final class PageSubscriptionImpl implements PageSubscription
          store.storeCursorAcknowledge(cursorId, position);
       }
 
-      store.afterCompleteOperations(new IOAsyncTask()
+      store.afterCompleteOperations(new IOCallback()
       {
          volatile String error = "";
 
@@ -541,7 +541,7 @@ final class PageSubscriptionImpl implements PageSubscription
          @Override
          public String toString()
          {
-            return IOAsyncTask.class.getSimpleName() + "(" + PageSubscriptionImpl.class.getSimpleName() + ") " + error;
+            return IOCallback.class.getSimpleName() + "(" + PageSubscriptionImpl.class.getSimpleName() + ") " + error;
          }
       });
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java
index 24d60df..ae41bb0 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java
@@ -25,8 +25,8 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
 import org.apache.activemq.artemis.core.paging.cursor.LivePageCache;
 import org.apache.activemq.artemis.core.paging.cursor.PageSubscriptionCounter;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
index 3a12b96..63681f2 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
@@ -29,9 +29,9 @@ import java.util.List;
 import java.util.concurrent.ScheduledExecutorService;
 
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.paging.PagingManager;
 import org.apache.activemq.artemis.core.paging.PagingStore;
 import org.apache.activemq.artemis.core.paging.PagingStoreFactory;
@@ -208,6 +208,6 @@ public class PagingStoreFactoryNIO implements PagingStoreFactory
 
    private SequentialFileFactory newFileFactory(final String directoryName)
    {
-      return new NIOSequentialFileFactory(new File(directory, directoryName), false, critialErrorListener);
+      return new NIOSequentialFileFactory(new File(directory, directoryName), false, critialErrorListener, 1);
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
index 3b0a139..6b67f3e 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
@@ -37,8 +37,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
 
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
 import org.apache.activemq.artemis.core.paging.PagingManager;
@@ -576,7 +576,7 @@ public class PagingStoreImpl implements PagingStore
    public boolean checkPageFileExists(final int pageNumber)
    {
       String fileName = createFileName(pageNumber);
-      SequentialFile file = fileFactory.createSequentialFile(fileName, 1);
+      SequentialFile file = fileFactory.createSequentialFile(fileName);
       return file.exists();
    }
 
@@ -589,7 +589,7 @@ public class PagingStoreImpl implements PagingStore
          fileFactory = storeFactory.newFileFactory(getStoreName());
       }
 
-      SequentialFile file = fileFactory.createSequentialFile(fileName, 1000);
+      SequentialFile file = fileFactory.createSequentialFile(fileName);
 
       Page page = new Page(storeName, storageManager, fileFactory, file, pageNumber);
 
@@ -1227,7 +1227,7 @@ public class PagingStoreImpl implements PagingStore
       {
          for (Integer id : pageIds)
          {
-            SequentialFile sFile = fileFactory.createSequentialFile(createFileName(id), 1);
+            SequentialFile sFile = fileFactory.createSequentialFile(createFileName(id));
             if (!sFile.exists())
             {
                continue;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java
index 2e1dd73..d13f311 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java
@@ -16,7 +16,7 @@
  */
 package org.apache.activemq.artemis.core.persistence;
 
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.journal.IOCompletion;
 
 /**
@@ -28,7 +28,7 @@ public interface OperationContext extends IOCompletion
 {
    /** Execute the task when all IO operations are complete,
     *  Or execute it immediately if nothing is pending.  */
-   void executeOnCompletion(IOAsyncTask runnable);
+   void executeOnCompletion(IOCallback runnable);
 
    void replicationLineUp();
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
index 5196ccc..7cf8112 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
@@ -25,10 +25,10 @@ import java.util.concurrent.Executor;
 
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.journal.Journal;
 import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.message.impl.MessageInternal;
 import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -99,7 +99,7 @@ public interface StorageManager extends IDGenerator, ActiveMQComponent
 
    void pageWrite(PagedMessage message, int pageNumber);
 
-   void afterCompleteOperations(IOAsyncTask run);
+   void afterCompleteOperations(IOCallback run);
 
    /**
     * Block until the operations are done.

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java
index 3c25164..210877c 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java
@@ -31,12 +31,12 @@ import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
 import org.apache.activemq.artemis.core.journal.impl.JournalReaderCallback;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.paging.cursor.impl.PageSubscriptionCounterImpl;
 import org.apache.activemq.artemis.core.paging.impl.PageTransactionInfoImpl;
 import org.apache.activemq.artemis.core.persistence.impl.journal.BatchingIDGenerator.IDCounterEncoding;
@@ -109,7 +109,7 @@ public final class DescribeJournal
    public static void describeBindingsJournal(final File bindingsDir) throws Exception
    {
 
-      SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(bindingsDir, null);
+      SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(bindingsDir, null, 1);
 
       JournalImpl bindings = new JournalImpl(1024 * 1024, 2, -1, 0, bindingsFF, "activemq-bindings", "bindings", 1);
       describeJournal(bindingsFF, bindings, bindingsDir);
@@ -118,7 +118,7 @@ public final class DescribeJournal
    public static DescribeJournal describeMessagesJournal(final File messagesDir) throws Exception
    {
 
-      SequentialFileFactory messagesFF = new NIOSequentialFileFactory(messagesDir, null);
+      SequentialFileFactory messagesFF = new NIOSequentialFileFactory(messagesDir, null, 1);
 
       // Will use only default values. The load function should adapt to anything different
       ConfigurationImpl defaultValues = new ConfigurationImpl();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
index 5104b68..33a1cbe 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
@@ -53,22 +53,22 @@ import org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException;
 import org.apache.activemq.artemis.api.core.Message;
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.filter.Filter;
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
 import org.apache.activemq.artemis.core.journal.Journal;
 import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.message.impl.MessageInternal;
 import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -236,7 +236,9 @@ public class JournalStorageManager implements StorageManager
       }
 
 
-      SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(config.getBindingsLocation(), criticalErrorListener);
+      SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(config.getBindingsLocation(),
+                                                                      criticalErrorListener,
+                                                                      config.getJournalMaxIO_NIO());
 
       Journal localBindings = new JournalImpl(1024 * 1024,
                                               2,
@@ -261,6 +263,7 @@ public class JournalStorageManager implements StorageManager
          journalFF = new AIOSequentialFileFactory(config.getJournalLocation(),
                                                   config.getJournalBufferSize_AIO(),
                                                   config.getJournalBufferTimeout_AIO(),
+                                                  config.getJournalMaxIO_AIO(),
                                                   config.isLogJournalWriteRate(),
                                                   criticalErrorListener);
       }
@@ -271,6 +274,7 @@ public class JournalStorageManager implements StorageManager
                                                   true,
                                                   config.getJournalBufferSize_NIO(),
                                                   config.getJournalBufferTimeout_NIO(),
+                                                  config.getJournalMaxIO_NIO(),
                                                   config.isLogJournalWriteRate(),
                                                   criticalErrorListener);
       }
@@ -296,7 +300,8 @@ public class JournalStorageManager implements StorageManager
 
       largeMessagesDirectory = config.getLargeMessagesDirectory();
 
-      largeMessagesFactory = new NIOSequentialFileFactory(config.getLargeMessagesLocation(), false, criticalErrorListener);
+      largeMessagesFactory = new NIOSequentialFileFactory(config.getLargeMessagesLocation(), false, criticalErrorListener,
+                                                          1);
 
       perfBlastPages = config.getJournalPerfBlastPages();
 
@@ -572,7 +577,7 @@ public class JournalStorageManager implements StorageManager
          String fileName = entry.getValue().getA();
          final long id = entry.getKey();
          long size = entry.getValue().getB();
-         SequentialFile seqFile = largeMessagesFactory.createSequentialFile(fileName, 1);
+         SequentialFile seqFile = largeMessagesFactory.createSequentialFile(fileName);
          if (!seqFile.exists())
             continue;
          replicator.syncLargeMessageFile(seqFile, size, id);
@@ -608,7 +613,7 @@ public class JournalStorageManager implements StorageManager
          if (!largeMessagesToDelete.contains(id))
          {
             idList.add(id);
-            SequentialFile seqFile = largeMessagesFactory.createSequentialFile(filename, 1);
+            SequentialFile seqFile = largeMessagesFactory.createSequentialFile(filename);
             long size = seqFile.size();
             largeMessages.put(id, new Pair<String, Long>(filename, size));
          }
@@ -747,7 +752,7 @@ public class JournalStorageManager implements StorageManager
       return new OperationContextImpl(executor1);
    }
 
-   public void afterCompleteOperations(final IOAsyncTask run)
+   public void afterCompleteOperations(final IOCallback run)
    {
       getContext().executeOnCompletion(run);
    }
@@ -2498,7 +2503,7 @@ public class JournalStorageManager implements StorageManager
 
    public SequentialFile createFileForLargeMessage(final long messageID, LargeMessageExtension extension)
    {
-      return largeMessagesFactory.createSequentialFile(messageID + extension.getExtension(), -1);
+      return largeMessagesFactory.createSequentialFile(messageID + extension.getExtension());
    }
 
 
@@ -2788,7 +2793,7 @@ public class JournalStorageManager implements StorageManager
          List<String> tmpFiles = largeMessagesFactory.listFiles("tmp");
          for (String tmpFile : tmpFiles)
          {
-            SequentialFile file = largeMessagesFactory.createSequentialFile(tmpFile, -1);
+            SequentialFile file = largeMessagesFactory.createSequentialFile(tmpFile);
             file.delete();
          }
       }
@@ -2830,7 +2835,7 @@ public class JournalStorageManager implements StorageManager
          return DummyOperationContext.instance;
       }
 
-      public void executeOnCompletion(final IOAsyncTask runnable)
+      public void executeOnCompletion(final IOCallback runnable)
       {
          // There are no executeOnCompletion calls while using the DummyOperationContext
          // However we keep the code here for correctness

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java
index dc09160..c4aa058 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java
@@ -24,7 +24,7 @@ import org.apache.activemq.artemis.api.core.ActiveMQException;
 import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
 import org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException;
 import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.message.BodyEncoder;
 import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
 import org.apache.activemq.artemis.core.server.LargeServerMessage;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java
index 76a8653..b034660 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java
@@ -20,7 +20,7 @@ import java.nio.ByteBuffer;
 
 import org.apache.activemq.artemis.api.core.ActiveMQException;
 import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.persistence.StorageManager;
 import org.apache.activemq.artemis.core.persistence.StorageManager.LargeMessageExtension;
 import org.apache.activemq.artemis.core.replication.ReplicatedLargeMessage;
@@ -62,7 +62,7 @@ public final class LargeServerMessageInSync implements ReplicatedLargeMessage
             buffer.rewind();
             int bytesRead = appendFile.read(buffer);
             if (bytesRead > 0)
-               mainSeqFile.writeInternal(buffer);
+               mainSeqFile.writeDirect(buffer, false);
             if (bytesRead < buffer.capacity())
             {
                break;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java
index 32eca26..a8e8e2a 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java
@@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.activemq.artemis.api.core.ActiveMQException;
 import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.journal.impl.SimpleWaitIOCallback;
 import org.apache.activemq.artemis.core.persistence.OperationContext;
 import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
@@ -134,7 +134,7 @@ public class OperationContextImpl implements OperationContext
       checkTasks();
    }
 
-   public void executeOnCompletion(final IOAsyncTask completion)
+   public void executeOnCompletion(final IOCallback completion)
    {
       if (errorCode != -1)
       {
@@ -219,7 +219,7 @@ public class OperationContextImpl implements OperationContext
    /**
     * @param task
     */
-   private void execute(final IOAsyncTask task)
+   private void execute(final IOCallback task)
    {
       executorsPending.incrementAndGet();
       try
@@ -243,7 +243,7 @@ public class OperationContextImpl implements OperationContext
       }
       catch (Throwable e)
       {
-         ActiveMQServerLogger.LOGGER.errorExecutingIOAsyncTask(e);
+         ActiveMQServerLogger.LOGGER.errorExecutingAIOCallback(e);
          executorsPending.decrementAndGet();
          task.onError(ActiveMQExceptionType.INTERNAL_ERROR.getCode(),
                       "It wasn't possible to complete IO operation - " + e.getMessage());
@@ -296,9 +296,9 @@ public class OperationContextImpl implements OperationContext
       final int replicationLined;
       final int pageLined;
 
-      final IOAsyncTask task;
+      final IOCallback task;
 
-      TaskHolder(final IOAsyncTask task)
+      TaskHolder(final IOCallback task)
       {
          storeLined = storeLineUp.intValue();
          replicationLined = replicationLineUp.intValue();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java
index 303e257..25cd0fc 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java
@@ -17,7 +17,7 @@
 package org.apache.activemq.artemis.core.persistence.impl.nullpm;
 
 import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.server.LargeServerMessage;
 import org.apache.activemq.artemis.core.server.ServerMessage;
 import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
index ade2173..d6336d2 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
@@ -27,10 +27,10 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.journal.Journal;
 import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.message.impl.MessageInternal;
 import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -112,7 +112,7 @@ public class NullStorageManager implements StorageManager
       }
 
       @Override
-      public void executeOnCompletion(final IOAsyncTask runnable)
+      public void executeOnCompletion(final IOCallback runnable)
       {
          runnable.done();
       }
@@ -359,7 +359,7 @@ public class NullStorageManager implements StorageManager
    }
 
    @Override
-   public void afterCompleteOperations(final IOAsyncTask run)
+   public void afterCompleteOperations(final IOCallback run)
    {
       run.done();
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
index 12bf669..71a2458 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
@@ -41,8 +41,8 @@ import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
 import org.apache.activemq.artemis.api.core.management.ManagementHelper;
 import org.apache.activemq.artemis.api.core.management.NotificationType;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.message.impl.MessageImpl;
 import org.apache.activemq.artemis.core.paging.PagingManager;
 import org.apache.activemq.artemis.core.paging.PagingStore;
@@ -1179,7 +1179,7 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
       {
          // This will use the same thread if there are no pending operations
          // avoiding a context switch on this case
-         storageManager.afterCompleteOperations(new IOAsyncTask()
+         storageManager.afterCompleteOperations(new IOCallback()
          {
             public void onError(final int errorCode, final String errorMessage)
             {
@@ -1249,7 +1249,7 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
          queues.addAll(durableQueues);
          queues.addAll(nonDurableQueues);
 
-         storageManager.afterCompleteOperations(new IOAsyncTask()
+         storageManager.afterCompleteOperations(new IOCallback()
          {
 
             public void onError(int errorCode, String errorMessage)

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
index 109d4fd..a39950e 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
@@ -58,8 +58,8 @@ import javax.transaction.xa.Xid;
 import org.apache.activemq.artemis.api.core.ActiveMQException;
 import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
 import org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.exception.ActiveMQXAException;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.persistence.StorageManager;
 import org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl;
 import org.apache.activemq.artemis.core.protocol.core.impl.wireformat.CreateQueueMessage;
@@ -614,7 +614,7 @@ public class ServerSessionPacketHandler implements ChannelHandler
                              final boolean flush,
                              final boolean closeChannel)
    {
-      storageManager.afterCompleteOperations(new IOAsyncTask()
+      storageManager.afterCompleteOperations(new IOCallback()
       {
          public void onError(final int errorCode, final String errorMessage)
          {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java
index 2723198..d96dbe1 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java
@@ -26,7 +26,7 @@ import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
 import org.apache.activemq.artemis.core.journal.LoaderCallback;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java
index ec16825..afb1e77 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java
@@ -34,11 +34,11 @@ import java.util.concurrent.TimeUnit;
 import org.apache.activemq.artemis.api.core.ActiveMQException;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
 import org.apache.activemq.artemis.core.journal.Journal;
 import org.apache.activemq.artemis.core.journal.Journal.JournalState;
 import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.journal.impl.FileWrapperJournal;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -546,7 +546,7 @@ public final class ReplicationEndpoint implements ChannelHandler, ActiveMQCompon
 
       if (!channel1.isOpen())
       {
-         channel1.open(1, false);
+         channel1.open();
       }
       channel1.writeDirect(ByteBuffer.wrap(data), true);
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java
index a2f39c9..905d7a5 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java
@@ -33,7 +33,7 @@ import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.client.SessionFailureListener;
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
 import org.apache.activemq.artemis.core.persistence.OperationContext;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
index b136990..11e6f61 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
@@ -43,10 +43,10 @@ import io.netty.channel.Channel;
 import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.client.impl.ServerLocatorInternal;
 import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.paging.cursor.PagePosition;
 import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
@@ -522,8 +522,8 @@ public interface ActiveMQServerLogger extends BasicLogger
    void lareMessageErrorCopying(@Cause Exception e, LargeServerMessage largeServerMessage);
 
    @LogMessage(level = Logger.Level.WARN)
-   @Message(id = 222054, value = "Error on executing IOAsyncTask", format = Message.Format.MESSAGE_FORMAT)
-   void errorExecutingIOAsyncTask(@Cause Throwable t);
+   @Message(id = 222054, value = "Error on executing IOCallback", format = Message.Format.MESSAGE_FORMAT)
+   void errorExecutingAIOCallback(@Cause Throwable t);
 
    @LogMessage(level = Logger.Level.WARN)
    @Message(id = 222055, value = "Error on deleting duplicate cache", format = Message.Format.MESSAGE_FORMAT)
@@ -1200,7 +1200,7 @@ public interface ActiveMQServerLogger extends BasicLogger
 
    @LogMessage(level = Logger.Level.ERROR)
    @Message(id = 224007, value = "page subscription = {0} error={1}", format = Message.Format.MESSAGE_FORMAT)
-   void pageSubscriptionError(IOAsyncTask ioAsyncTask, String error);
+   void pageSubscriptionError(IOCallback IOCallback, String error);
 
    @LogMessage(level = Logger.Level.ERROR)
    @Message(id = 224008, value = "Failed to store id", format = Message.Format.MESSAGE_FORMAT)

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java
index 57120ff..e22a172 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java
@@ -17,7 +17,7 @@
 package org.apache.activemq.artemis.core.server;
 
 import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
 import org.apache.activemq.artemis.core.replication.ReplicatedLargeMessage;
 
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java
index 3c0ba41..106158c 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java
@@ -22,8 +22,8 @@ import java.util.concurrent.Executor;
 
 import org.apache.activemq.artemis.api.core.Message;
 import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.persistence.StorageManager;
 import org.apache.activemq.artemis.core.postoffice.PostOffice;
 import org.apache.activemq.artemis.core.server.Consumer;
@@ -247,7 +247,7 @@ public class Redistributor implements Consumer
 
       tx.commit();
 
-      storageManager.afterCompleteOperations(new IOAsyncTask()
+      storageManager.afterCompleteOperations(new IOCallback()
       {
 
          public void onError(final int errorCode, final String errorMessage)

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java
index 7adee2e..2d0f3c0 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java
@@ -17,10 +17,11 @@
 package org.apache.activemq.artemis.core.server.impl;
 
 import java.io.File;
-import java.io.IOException;
 import java.nio.channels.FileLock;
 
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
+import org.apache.activemq.artemis.core.io.aio.ActiveMQFileLock;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
 
 /**
  * This is using the ActiveMQ Artemis Libaio Native to perform calls to flock on a Linux system. At the
@@ -56,19 +57,15 @@ public final class AIOFileLockNodeManager extends FileLockNodeManager
    {
       File file = newFileForRegionLock(lockPos);
 
-      int handle = AsynchronousFileImpl.openFile(file.getAbsolutePath());
+      LibaioFile fileControl = LibaioContext.openControlFile(file.getAbsolutePath(), false);
 
-      if (handle < 0)
+      if (!fileControl.lock())
       {
-         throw new IOException("couldn't open file " + file.getAbsolutePath());
+         fileControl.close();
+         return null;
       }
 
-      FileLock lock = AsynchronousFileImpl.lock(handle);
-
-      if (lock == null)
-      {
-         AsynchronousFileImpl.closeFile(handle);
-      }
+      FileLock lock = new ActiveMQFileLock(fileControl);
 
       return lock;
 
@@ -83,21 +80,13 @@ public final class AIOFileLockNodeManager extends FileLockNodeManager
 
       while (!interrupted)
       {
-         int handle = AsynchronousFileImpl.openFile(file.getAbsolutePath());
-
-         if (handle < 0)
-         {
-            throw new IOException("couldn't open file " + file.getAbsolutePath());
-         }
-
-         FileLock lockFile = AsynchronousFileImpl.lock(handle);
+         FileLock lockFile = tryLock(liveLockPos);
          if (lockFile != null)
          {
             return lockFile;
          }
          else
          {
-            AsynchronousFileImpl.closeFile(handle);
             try
             {
                Thread.sleep(500);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index 0dc85de..9d7e95b 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -19,7 +19,6 @@ package org.apache.activemq.artemis.core.server.impl;
 import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl;
 import org.apache.activemq.artemis.core.config.BridgeConfiguration;
 import org.apache.activemq.artemis.core.config.Configuration;
@@ -29,11 +28,10 @@ import org.apache.activemq.artemis.core.config.DivertConfiguration;
 import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
 import org.apache.activemq.artemis.core.filter.Filter;
 import org.apache.activemq.artemis.core.filter.impl.FilterImpl;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
 import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.SyncSpeedTest;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.management.impl.ActiveMQServerControlImpl;
 import org.apache.activemq.artemis.core.paging.PagingManager;
 import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
@@ -96,6 +94,7 @@ import org.apache.activemq.artemis.core.settings.impl.ResourceLimitSettings;
 import org.apache.activemq.artemis.core.transaction.ResourceManager;
 import org.apache.activemq.artemis.core.transaction.impl.ResourceManagerImpl;
 import org.apache.activemq.artemis.core.version.Version;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
 import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
 import org.apache.activemq.artemis.spi.core.protocol.SessionCallback;
@@ -359,7 +358,7 @@ public class ActiveMQServerImpl implements ActiveMQServer
       {
          manager = new InVMNodeManager(replicatingBackup);
       }
-      else if (configuration.getJournalType() == JournalType.ASYNCIO && AsynchronousFileImpl.isLoaded())
+      else if (configuration.getJournalType() == JournalType.ASYNCIO && LibaioContext.isLoaded())
       {
          manager = new AIOFileLockNodeManager(directory, replicatingBackup, configuration.getJournalLockAcquisitionTimeout());
       }
@@ -401,13 +400,6 @@ public class ActiveMQServerImpl implements ActiveMQServer
 
          ActiveMQServerLogger.LOGGER.serverStarting((haPolicy.isBackup() ? "backup" : "live"), configuration);
 
-         if (configuration.isRunSyncSpeedTest())
-         {
-            SyncSpeedTest test = new SyncSpeedTest();
-
-            test.run();
-         }
-
          final boolean wasLive = !haPolicy.isBackup();
          if (!haPolicy.isBackup())
          {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
index 29a4509..92cdbf9 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
@@ -45,8 +45,8 @@ import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
 import org.apache.activemq.artemis.api.core.management.ManagementHelper;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.message.impl.MessageImpl;
 import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
 import org.apache.activemq.artemis.core.paging.cursor.PagedReference;
@@ -2524,7 +2524,7 @@ public class QueueImpl implements Queue
 
       acknowledge(tx, ref);
 
-      storageManager.afterCompleteOperations(new IOAsyncTask()
+      storageManager.afterCompleteOperations(new IOCallback()
       {
 
          public void onError(final int errorCode, final String errorMessage)

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
index 98b6bb7..49a3926 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
@@ -39,11 +39,11 @@ import org.apache.activemq.artemis.api.core.client.ClientSession;
 import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
 import org.apache.activemq.artemis.api.core.management.ManagementHelper;
 import org.apache.activemq.artemis.api.core.management.ResourceNames;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.client.impl.ClientMessageImpl;
 import org.apache.activemq.artemis.core.exception.ActiveMQXAException;
 import org.apache.activemq.artemis.core.filter.Filter;
 import org.apache.activemq.artemis.core.filter.impl.FilterImpl;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.message.impl.MessageInternal;
 import org.apache.activemq.artemis.core.paging.PagingStore;
 import org.apache.activemq.artemis.core.persistence.OperationContext;
@@ -1395,7 +1395,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener
    public void close(final boolean failed)
    {
       if (closed) return;
-      context.executeOnCompletion(new IOAsyncTask()
+      context.executeOnCompletion(new IOCallback()
       {
          public void onError(int errorCode, String errorMessage)
          {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java
index 42aab20..357ce6f 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java
@@ -23,7 +23,7 @@ import java.util.Date;
 import java.util.List;
 
 import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.persistence.StorageManager;
 import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
 import org.apache.activemq.artemis.core.server.Queue;
@@ -197,7 +197,7 @@ public class TransactionImpl implements Transaction
             // We use the Callback even for non persistence
             // If we are using non-persistence with replication, the replication manager will have
             // to execute this runnable in the correct order
-            storageManager.afterCompleteOperations(new IOAsyncTask()
+            storageManager.afterCompleteOperations(new IOCallback()
             {
 
                public void onError(final int errorCode, final String errorMessage)
@@ -266,7 +266,7 @@ public class TransactionImpl implements Transaction
          // to execute this runnable in the correct order
          // This also will only use a different thread if there are any IO pending.
          // If the IO finished early by the time we got here, we won't need an executor
-         storageManager.afterCompleteOperations(new IOAsyncTask()
+         storageManager.afterCompleteOperations(new IOCallback()
          {
 
             public void onError(final int errorCode, final String errorMessage)
@@ -323,7 +323,7 @@ public class TransactionImpl implements Transaction
          // We use the Callback even for non persistence
          // If we are using non-persistence with replication, the replication manager will have
          // to execute this runnable in the correct order
-         storageManager.afterCompleteOperations(new IOAsyncTask()
+         storageManager.afterCompleteOperations(new IOCallback()
          {
 
             public void onError(final int errorCode, final String errorMessage)

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
index 26e9bb5..4142f1f 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
@@ -67,7 +67,6 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
 import org.apache.activemq.artemis.api.core.client.ClientSession;
 import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
 import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl;
 import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal;
 import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl;
@@ -78,11 +77,11 @@ import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
 import org.apache.activemq.artemis.core.journal.impl.JournalReaderCallback;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.paging.PagingStore;
 import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
 import org.apache.activemq.artemis.core.postoffice.Binding;
@@ -117,6 +116,7 @@ import org.apache.activemq.artemis.core.server.impl.SharedNothingBackupActivatio
 import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
 import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
 import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManagerImpl;
 import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
@@ -574,7 +574,7 @@ public abstract class ActiveMQTestBase extends Assert
 
    public static JournalType getDefaultJournalType()
    {
-      if (AsynchronousFileImpl.isLoaded())
+      if (LibaioContext.isLoaded())
       {
          return JournalType.ASYNCIO;
       }
@@ -1894,7 +1894,7 @@ public abstract class ActiveMQTestBase extends Assert
       JournalImpl messagesJournal = null;
       try
       {
-         SequentialFileFactory messagesFF = new NIOSequentialFileFactory(new File(getJournalDir()), null);
+         SequentialFileFactory messagesFF = new NIOSequentialFileFactory(new File(getJournalDir()), null, 1);
 
          messagesJournal = new JournalImpl(config.getJournalFileSize(),
                                            config.getJournalMinFiles(),
@@ -1940,7 +1940,7 @@ public abstract class ActiveMQTestBase extends Assert
    protected HashMap<Integer, AtomicInteger> countJournal(Configuration config) throws Exception
    {
       final HashMap<Integer, AtomicInteger> recordsType = new HashMap<Integer, AtomicInteger>();
-      SequentialFileFactory messagesFF = new NIOSequentialFileFactory(config.getJournalLocation(), null);
+      SequentialFileFactory messagesFF = new NIOSequentialFileFactory(config.getJournalLocation(), null, 1);
 
       JournalImpl messagesJournal = new JournalImpl(config.getJournalFileSize(),
                                                     config.getJournalMinFiles(),
@@ -1988,7 +1988,7 @@ public abstract class ActiveMQTestBase extends Assert
 
       if (messageJournal)
       {
-         ff = new NIOSequentialFileFactory(config.getJournalLocation(), null);
+         ff = new NIOSequentialFileFactory(config.getJournalLocation(), null, 1);
          journal = new JournalImpl(config.getJournalFileSize(),
                                    config.getJournalMinFiles(),
                                    0,
@@ -2000,7 +2000,7 @@ public abstract class ActiveMQTestBase extends Assert
       }
       else
       {
-         ff = new NIOSequentialFileFactory(config.getBindingsLocation(), null);
+         ff = new NIOSequentialFileFactory(config.getBindingsLocation(), null, 1);
          journal = new JournalImpl(1024 * 1024,
                                    2,
                                    config.getJournalCompactMinFiles(),
@@ -2403,31 +2403,31 @@ public abstract class ActiveMQTestBase extends Assert
 
       long timeout = System.currentTimeMillis() + 15000;
 
-      while (AsynchronousFileImpl.getTotalMaxIO() != 0 && System.currentTimeMillis() > timeout)
-      {
-         try
-         {
-            Thread.sleep(100);
-         }
-         catch (Exception ignored)
-         {
-         }
-      }
-
-      int invmSize = InVMRegistry.instance.size();
-      if (invmSize > 0)
-      {
-         InVMRegistry.instance.clear();
-         log.info(threadDump("Thread dump"));
-         fail("invm registry still had acceptors registered");
-      }
-
-      final int totalMaxIO = AsynchronousFileImpl.getTotalMaxIO();
-      if (totalMaxIO != 0)
-      {
-         AsynchronousFileImpl.resetMaxAIO();
-         Assert.fail("test did not close all its files " + totalMaxIO);
-      }
+//      while (AsynchronousFileImpl.getTotalMaxIO() != 0 && System.currentTimeMillis() > timeout)
+//      {
+//         try
+//         {
+//            Thread.sleep(100);
+//         }
+//         catch (Exception ignored)
+//         {
+//         }
+//      }
+//
+//      int invmSize = InVMRegistry.instance.size();
+//      if (invmSize > 0)
+//      {
+//         InVMRegistry.instance.clear();
+//         log.info(threadDump("Thread dump"));
+//         fail("invm registry still had acceptors registered");
+//      }
+//
+//      final int totalMaxIO = AsynchronousFileImpl.getTotalMaxIO();
+//      if (totalMaxIO != 0)
+//      {
+//         AsynchronousFileImpl.resetMaxAIO();
+//         Assert.fail("test did not close all its files " + totalMaxIO);
+//      }
    }
 
    private void cleanupPools()

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java
index 4f9dd48..845c9da 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java
@@ -17,18 +17,17 @@
 package org.apache.activemq.artemis.tests.util;
 
 import javax.management.MBeanServer;
-
 import java.io.File;
 
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.core.server.JournalType;
 import org.apache.activemq.artemis.core.server.NodeManager;
 import org.apache.activemq.artemis.core.server.impl.AIOFileLockNodeManager;
-import org.apache.activemq.artemis.core.server.impl.FileLockNodeManager;
 import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
+import org.apache.activemq.artemis.core.server.impl.FileLockNodeManager;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
 
 
@@ -69,7 +68,7 @@ public class ColocatedActiveMQServer extends ActiveMQServerImpl
       if (replicatingBackup)
       {
          NodeManager manager;
-         if (getConfiguration().getJournalType() == JournalType.ASYNCIO && AsynchronousFileImpl.isLoaded())
+         if (getConfiguration().getJournalType() == JournalType.ASYNCIO && LibaioContext.isLoaded())
          {
             return new AIOFileLockNodeManager(directory, replicatingBackup, getConfiguration().getJournalLockAcquisitionTimeout());
          }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
index a6bce80..4332fbd 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
@@ -37,9 +37,9 @@ import org.apache.activemq.artemis.api.core.client.ServerLocator;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.filter.Filter;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
 import org.apache.activemq.artemis.core.persistence.OperationContext;
 import org.apache.activemq.artemis.core.persistence.StorageManager;
@@ -480,7 +480,7 @@ public class HangConsumerTest extends ActiveMQTestBase
 
             server.stop();
 
-            SequentialFileFactory messagesFF = new NIOSequentialFileFactory(server.getConfiguration().getBindingsLocation(), null);
+            SequentialFileFactory messagesFF = new NIOSequentialFileFactory(server.getConfiguration().getBindingsLocation(), null, 1);
 
             JournalImpl messagesJournal = new JournalImpl(1024 * 1024,
                                                           2,

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java
index e71189f..cbc2904 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java
@@ -33,7 +33,7 @@ import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.junit.Assert;
@@ -221,7 +221,7 @@ public class JournalCrashTest extends ActiveMQTestBase
     */
    private void printJournal() throws Exception
    {
-      NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getJournalDir()));
+      NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getJournalDir()), 100);
       JournalImpl journal = new JournalImpl(ActiveMQDefaultConfiguration.getDefaultJournalFileSize(),
                                             2,
                                             0,

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java
index 4e6191e..9044b28 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.activemq.artemis.tests.integration.client;
 
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.junit.Test;
 
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 
 /**
@@ -45,7 +45,7 @@ public class LibaioDependencyCheckTest extends ActiveMQTestBase
    {
       if (System.getProperties().get("os.name").equals("Linux"))
       {
-         assertTrue("Libaio is not available on this platform", AsynchronousFileImpl.isLoaded());
+         assertTrue("Libaio is not available on this platform", LibaioContext.isLoaded());
       }
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
index 9d0d4d7..b870639 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
@@ -46,15 +46,15 @@ import org.apache.activemq.artemis.api.core.client.ClientSession;
 import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
 import org.apache.activemq.artemis.api.core.client.MessageHandler;
 import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.config.DivertConfiguration;
 import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
 import org.apache.activemq.artemis.core.paging.PagingManager;
 import org.apache.activemq.artemis.core.paging.PagingStore;
@@ -1734,7 +1734,7 @@ public class PagingTest extends ActiveMQTestBase
                                         2,
                                         0,
                                         0,
-                                        new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation()),
+                                        new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation(), 1),
                                         "activemq-data",
                                         "amq",
                                         1);
@@ -6454,7 +6454,7 @@ public class PagingTest extends ActiveMQTestBase
          pageDone.countDown();
       }
 
-      public void executeOnCompletion(IOAsyncTask runnable)
+      public void executeOnCompletion(IOCallback runnable)
       {
 
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java
index 460c4df..dea83e6 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java
@@ -32,7 +32,7 @@ import org.apache.activemq.artemis.core.journal.LoaderCallback;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
@@ -297,7 +297,7 @@ public class RedeliveryConsumerTest extends ActiveMQTestBase
                                             2,
                                             0,
                                             0,
-                                            new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation()),
+                                            new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation(), 1),
                                             "activemq-data",
                                             "amq",
                                             1);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java
index ede895f..151e2b4 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java
@@ -45,9 +45,9 @@ import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.config.CoreQueueConfiguration;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal;
 import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
 import org.apache.activemq.artemis.core.postoffice.DuplicateIDCache;
@@ -1923,7 +1923,7 @@ public class BridgeTest extends ActiveMQTestBase
    protected Map<Long, AtomicInteger> loadQueues(ActiveMQServer serverToInvestigate) throws Exception
    {
       SequentialFileFactory messagesFF = new NIOSequentialFileFactory(serverToInvestigate.getConfiguration()
-                                                                              .getJournalLocation());
+                                                                              .getJournalLocation(), 1);
 
       JournalImpl messagesJournal = new JournalImpl(serverToInvestigate.getConfiguration().getJournalFileSize(),
                                                     serverToInvestigate.getConfiguration().getJournalMinFiles(),


[4/9] activemq-artemis git commit: ARTEMIS-163 First pass on the native AIO refactoring

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.c
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.c b/artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.c
new file mode 100644
index 0000000..b6fcdd3
--- /dev/null
+++ b/artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.c
@@ -0,0 +1,710 @@
+/*
+ * 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.
+ */
+
+#ifndef _GNU_SOURCE
+// libaio, O_DIRECT and other things won't be available without this define
+#define _GNU_SOURCE
+#endif
+
+//#define DEBUG
+
+#include <jni.h>
+#include <unistd.h>
+#include <errno.h>
+#include <libaio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "org_apache_activemq_artemis_jlibaio_LibaioContext.h"
+#include "exception_helper.h"
+
+struct io_control {
+    io_context_t ioContext;
+    struct io_event * events;
+
+    jobject thisObject;
+
+    // This is used to make sure we don't return IOCB while something else is using them
+    // this is to guarantee the submits could be done concurrently with polling
+    pthread_mutex_t iocbLock;
+
+    pthread_mutex_t pollLock;
+
+    // a resuable pool of iocb
+    struct iocb ** iocb;
+    int queueSize;
+    int iocbPut;
+    int iocbGet;
+    int used;
+};
+
+jclass submitClass = NULL;
+jmethodID errorMethod = NULL;
+jmethodID doneMethod = NULL;
+jmethodID libaioContextDone = NULL;
+
+jclass libaioContextClass = NULL;
+jclass runtimeExceptionClass = NULL;
+jclass ioExceptionClass = NULL;
+
+// util methods
+void throwRuntimeException(JNIEnv* env, char* message) {
+    (*env)->ThrowNew(env, runtimeExceptionClass, message);
+}
+
+void throwRuntimeExceptionErrorNo(JNIEnv* env, char* message, int errorNumber) {
+    char* allocatedMessage = exceptionMessage(message, errorNumber);
+    (*env)->ThrowNew(env, runtimeExceptionClass, allocatedMessage);
+    free(allocatedMessage);
+}
+
+void throwIOException(JNIEnv* env, char* message) {
+    (*env)->ThrowNew(env, ioExceptionClass, message);
+}
+
+void throwIOExceptionErrorNo(JNIEnv* env, char* message, int errorNumber) {
+    char* allocatedMessage = exceptionMessage(message, errorNumber);
+    (*env)->ThrowNew(env, ioExceptionClass, allocatedMessage);
+    free(allocatedMessage);
+}
+
+void throwOutOfMemoryError(JNIEnv* env) {
+    jclass exceptionClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+    (*env)->ThrowNew(env, exceptionClass, "");
+}
+
+/** Notice: every usage of exceptionMessage needs to release the allocated memory for the sequence of char */
+char* exceptionMessage(char* msg, int error) {
+    if (error < 0) {
+        // some functions return negative values
+        // and it's hard to keep track of when to send -error and when not
+        // this will just take care when things are forgotten
+        // what would generate a proper error
+        error = error * -1;
+    }
+    //strerror is returning a constant, so no need to free anything coming from strerror
+    char* err = strerror(error);
+    char* result = malloc(strlen(msg) + strlen(err) + 1);
+    strcpy(result, msg);
+    strcat(result, err);
+    return result;
+}
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+    JNIEnv* env;
+    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
+        return JNI_ERR;
+    } else {
+        jclass localRuntimeExceptionClass = (*env)->FindClass(env, "java/lang/RuntimeException");
+        if (localRuntimeExceptionClass == NULL) {
+            // pending exception...
+            return JNI_ERR;
+        }
+        runtimeExceptionClass = (jclass) (*env)->NewGlobalRef(env, localRuntimeExceptionClass);
+        if (runtimeExceptionClass == NULL) {
+            // out-of-memory!
+            throwOutOfMemoryError(env);
+            return JNI_ERR;
+        }
+
+        jclass localIoExceptionClass = (*env)->FindClass(env, "java/io/IOException");
+        if (localIoExceptionClass == NULL) {
+            // pending exception...
+            return JNI_ERR;
+        }
+        ioExceptionClass = (jclass) (*env)->NewGlobalRef(env, localIoExceptionClass);
+        if (ioExceptionClass == NULL) {
+            // out-of-memory!
+            throwOutOfMemoryError(env);
+            return JNI_ERR;
+        }
+
+        submitClass = (*env)->FindClass(env, "org/apache/activemq/artemis/jlibaio/SubmitInfo");
+        if (submitClass == NULL) {
+           return JNI_ERR;
+        }
+
+        submitClass = (jclass)(*env)->NewGlobalRef(env, (jobject)submitClass);
+
+        errorMethod = (*env)->GetMethodID(env, submitClass, "onError", "(ILjava/lang/String;)V");
+        if (errorMethod == NULL) {
+           return JNI_ERR;
+        }
+        errorMethod = (jmethodID)(*env)->NewGlobalRef(env, (jobject)(errorMethod));
+
+        doneMethod = (*env)->GetMethodID(env, submitClass, "done", "()V");
+        if (doneMethod == NULL) {
+           return JNI_ERR;
+        }
+        doneMethod = (jmethodID)(*env)->NewGlobalRef(env, (jobject)(doneMethod));
+
+        libaioContextClass = (*env)->FindClass(env, "org/apache/activemq/artemis/jlibaio/LibaioContext");
+        if (libaioContextClass == NULL) {
+           return JNI_ERR;
+        }
+        libaioContextClass = (jclass)(*env)->NewGlobalRef(env, (jobject)libaioContextClass);
+
+        libaioContextDone = (*env)->GetMethodID(env, libaioContextClass, "done", "(Lorg/apache/activemq/artemis/jlibaio/SubmitInfo;)V");
+        if (libaioContextDone == NULL) {
+           return JNI_ERR;
+        }
+        libaioContextDone = (jmethodID)(*env)->NewGlobalRef(env, (jobject)libaioContextDone);
+
+        return JNI_VERSION_1_6;
+    }
+}
+
+void JNI_OnUnload(JavaVM* vm, void* reserved) {
+    JNIEnv* env;
+    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
+        // Something is wrong but nothing we can do about this :(
+        return;
+    } else {
+        // delete global references so the GC can collect them
+        if (runtimeExceptionClass != NULL) {
+            (*env)->DeleteGlobalRef(env, runtimeExceptionClass);
+        }
+        if (ioExceptionClass != NULL) {
+            (*env)->DeleteGlobalRef(env, ioExceptionClass);
+        }
+
+        // Deleting global refs so their classes can be GCed
+        if (errorMethod != NULL) {
+            (*env)->DeleteGlobalRef(env, (jobject)errorMethod);
+        }
+
+        if (doneMethod != NULL) {
+            (*env)->DeleteGlobalRef(env, (jobject)doneMethod);
+        }
+
+        if (submitClass != NULL) {
+            (*env)->DeleteGlobalRef(env, (jobject)submitClass);
+        }
+
+        if (libaioContextClass != NULL) {
+            (*env)->DeleteGlobalRef(env, (jobject)libaioContextClass);
+        }
+
+        if (libaioContextDone != NULL) {
+            (*env)->DeleteGlobalRef(env, (jobject)libaioContextDone);
+        }
+    }
+}
+
+static inline struct io_control * getIOControl(JNIEnv* env, jobject pointer) {
+    struct io_control * ioControl = (struct io_control *) (*env)->GetDirectBufferAddress(env, pointer);
+    if (ioControl == NULL) {
+       throwRuntimeException(env, "Controller not initialized");
+    }
+    return ioControl;
+}
+
+/**
+ * remove an iocb from the pool of IOCBs. Returns null if full
+ */
+static inline struct iocb * getIOCB(struct io_control * control) {
+    struct iocb * iocb = 0;
+
+    pthread_mutex_lock(&(control->iocbLock));
+
+    #ifdef DEBUG
+       fprintf (stdout, "getIOCB::used=%d, queueSize=%d, get=%d, put=%d\n", control->used, control->queueSize, control->iocbGet, control->iocbPut);
+    #endif
+
+    if (control->used < control->queueSize) {
+        control->used++;
+        iocb = control->iocb[control->iocbGet++];
+
+        if (control->iocbGet >= control->queueSize) {
+           control->iocbGet = 0;
+        }
+    }
+
+    pthread_mutex_unlock(&(control->iocbLock));
+    return iocb;
+}
+
+/**
+ * Put an iocb back on the pool of IOCBs
+ */
+static inline void putIOCB(struct io_control * control, struct iocb * iocbBack) {
+    pthread_mutex_lock(&(control->iocbLock));
+
+    #ifdef DEBUG
+       fprintf (stdout, "putIOCB::used=%d, queueSize=%d, get=%d, put=%d\n", control->used, control->queueSize, control->iocbGet, control->iocbPut);
+    #endif
+
+    control->used--;
+    control->iocb[control->iocbPut++] = iocbBack;
+    if (control->iocbPut >= control->queueSize) {
+       control->iocbPut = 0;
+    }
+    pthread_mutex_unlock(&(control->iocbLock));
+}
+
+static inline void * getBuffer(JNIEnv* env, jobject pointer) {
+    return (*env)->GetDirectBufferAddress(env, pointer);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_lock
+  (JNIEnv * env, jclass  clazz, jint handle) {
+    return flock(handle, LOCK_EX | LOCK_NB) == 0;
+}
+
+/**
+ * Everything that is allocated here will be freed at deleteContext when the class is unloaded.
+ */
+JNIEXPORT jobject JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_newContext(JNIEnv* env, jobject thisObject, jint queueSize) {
+    io_context_t libaioContext;
+    int i = 0;
+
+    #ifdef DEBUG
+        fprintf (stdout, "Initializing context\n");
+    #endif
+
+    int res = io_queue_init(queueSize, &libaioContext);
+    if (res) {
+        // Error, so need to release whatever was done before
+        free(libaioContext);
+
+        throwRuntimeExceptionErrorNo(env, "Cannot initialize queue:", res);
+        return NULL;
+    }
+
+    struct iocb ** iocb = (struct iocb **)malloc((sizeof(struct iocb *) * (size_t)queueSize));
+    if (iocb == NULL) {
+       throwOutOfMemoryError(env);
+       return NULL;
+    }
+
+    for (i = 0; i < queueSize; i++) {
+       iocb[i] = (struct iocb *)malloc(sizeof(struct iocb));
+       if (iocb[i] == NULL) {
+           // it's unlikely this would happen at this point
+           // for that reason I'm not cleaning up individual IOCBs here
+           // we could increase support here with a cleanup of any previously allocated iocb
+           // But I'm afraid of adding not needed complexity here
+           throwOutOfMemoryError(env);
+           return NULL;
+       }
+    }
+
+    struct io_control * theControl = (struct io_control *) malloc(sizeof(struct io_control));
+    if (theControl == NULL) {
+        throwOutOfMemoryError(env);
+        return NULL;
+    }
+
+    res = pthread_mutex_init(&(theControl->iocbLock), 0);
+    if (res) {
+        free(theControl);
+        free(libaioContext);
+        throwRuntimeExceptionErrorNo(env, "Can't initialize mutext:", res);
+        return NULL;
+    }
+
+    res = pthread_mutex_init(&(theControl->pollLock), 0);
+    if (res) {
+        free(theControl);
+        free(libaioContext);
+        throwRuntimeExceptionErrorNo(env, "Can't initialize mutext:", res);
+        return NULL;
+    }
+
+    struct io_event * events = (struct io_event *)malloc(sizeof(struct io_event) * (size_t)queueSize);
+
+    theControl->ioContext = libaioContext;
+    theControl->events = events;
+    theControl->iocb = iocb;
+    theControl->queueSize = queueSize;
+    theControl->iocbPut = 0;
+    theControl->iocbGet = 0;
+    theControl->used = 0;
+    theControl->thisObject = (*env)->NewGlobalRef(env, thisObject);
+
+    return (*env)->NewDirectByteBuffer(env, theControl, sizeof(struct io_control));
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_deleteContext(JNIEnv* env, jclass clazz, jobject contextPointer) {
+    int i;
+    struct io_control * theControl = getIOControl(env, contextPointer);
+    if (theControl == NULL) {
+      return;
+    }
+
+    io_queue_release(theControl->ioContext);
+
+    // to make sure the poll has finished
+    pthread_mutex_lock(&(theControl->pollLock));
+    pthread_mutex_unlock(&(theControl->pollLock));
+
+    pthread_mutex_destroy(&(theControl->pollLock));
+    pthread_mutex_destroy(&(theControl->iocbLock));
+
+    // Releasing each individual iocb
+    for (i = 0; i < theControl->queueSize; i++) {
+       free(theControl->iocb[i]);
+    }
+
+    (*env)->DeleteGlobalRef(env, theControl->thisObject);
+
+    free(theControl->iocb);
+    free(theControl->events);
+    free(theControl);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_close(JNIEnv* env, jclass clazz, jint fd) {
+   if (close(fd) < 0) {
+       throwIOExceptionErrorNo(env, "Error closing file:", errno);
+   }
+}
+
+JNIEXPORT int JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_open(JNIEnv* env, jclass clazz,
+                        jstring path, jboolean direct) {
+    const char* f_path = (*env)->GetStringUTFChars(env, path, 0);
+
+    int res;
+    if (direct) {
+      res = open(f_path, O_RDWR | O_CREAT | O_DIRECT, 0666);
+    } else {
+      res = open(f_path, O_RDWR | O_CREAT, 0666);
+    }
+
+    (*env)->ReleaseStringUTFChars(env, path, f_path);
+
+    if (res < 0) {
+       throwIOExceptionErrorNo(env, "Cannot open file:", errno);
+    }
+
+    return res;
+}
+
+static inline void submit(JNIEnv * env, struct io_control * theControl, struct iocb * iocb) {
+    int result = io_submit(theControl->ioContext, 1, &iocb);
+
+    if (result < 0) {
+        // Putting the Global Ref and IOCB back in case of a failure
+        (*env)->DeleteGlobalRef(env, (jobject)iocb->data);
+        putIOCB(theControl, iocb);
+
+        throwIOExceptionErrorNo(env, "Error while submitting IO: ", -result);
+    }
+
+    return;
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_submitWrite
+  (JNIEnv * env, jclass clazz, jint fileHandle, jobject contextPointer, jlong position, jint size, jobject bufferWrite, jobject callback) {
+    struct io_control * theControl = getIOControl(env, contextPointer);
+    if (theControl == NULL) {
+      return;
+    }
+
+    #ifdef DEBUG
+       fprintf (stdout, "submitWrite position %ld, size %d\n", position, size);
+    #endif
+
+    struct iocb * iocb = getIOCB(theControl);
+
+    if (iocb == NULL) {
+        throwIOException(env, "Not enough space in libaio queue");
+        return;
+    }
+
+    io_prep_pwrite(iocb, fileHandle, getBuffer(env, bufferWrite), (size_t)size, position);
+
+    // The GlobalRef will be deleted when poll is called. this is done so
+    // the vm wouldn't crash if the Callback passed by the user is GCed between submission
+    // and callback.
+    // also as the real intention is to hold the reference until the life cycle is complete
+    iocb->data = (void *) (*env)->NewGlobalRef(env, callback);
+
+    return submit(env, theControl, iocb);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_submitRead
+  (JNIEnv * env, jclass clazz, jint fileHandle, jobject contextPointer, jlong position, jint size, jobject bufferRead, jobject callback) {
+    struct io_control * theControl = getIOControl(env, contextPointer);
+    if (theControl == NULL) {
+      return;
+    }
+
+    struct iocb * iocb = getIOCB(theControl);
+
+    if (iocb == NULL) {
+        throwIOException(env, "Not enough space in libaio queue");
+        return;
+    }
+
+    io_prep_pread(iocb, fileHandle, getBuffer(env, bufferRead), (size_t)size, position);
+
+    // The GlobalRef will be deleted when poll is called. this is done so
+    // the vm wouldn't crash if the Callback passed by the user is GCed between submission
+    // and callback.
+    // also as the real intention is to hold the reference until the life cycle is complete
+    iocb->data = (void *) (*env)->NewGlobalRef(env, callback);
+
+    return submit(env, theControl, iocb);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_blockedPoll
+  (JNIEnv * env, jobject thisObject, jobject contextPointer) {
+
+    #ifdef DEBUG
+       fprintf (stdout, "Running blockedPoll");
+    #endif
+
+    int i;
+    struct io_control * theControl = getIOControl(env, contextPointer);
+    if (theControl == NULL) {
+      return;
+    }
+    int max = theControl->queueSize;
+    pthread_mutex_lock(&(theControl->pollLock));
+
+    for (;;) {
+
+        int result = io_getevents(theControl->ioContext, 1, max, theControl->events, 0);
+
+        if (result < 0)
+        {
+            #ifdef DEBUG
+               fprintf (stdout, "finished blockedPoll rutine with result=%d\n", result);
+            #endif
+            break;
+        }
+        #ifdef DEBUG
+           fprintf (stdout, "blockedPoll returned %d events\n", result);
+        #endif
+
+        for (i = 0; i < result; i++)
+        {
+            #ifdef DEBUG
+               fprintf (stdout, "blockedPoll treading event %d\n", i);
+            #endif
+            struct io_event * event = &(theControl->events[i]);
+            struct iocb * iocbp = event->obj;
+            int eventResult = (int)event->res;
+
+            #ifdef DEBUG
+                fprintf (stdout, "Poll res: %d totalRes=%d\n", eventResult, result);
+            #endif
+
+            if (eventResult < 0) {
+                #ifdef DEBUG
+                    fprintf (stdout, "Error: %s\n", strerror(-eventResult));
+                #endif
+
+                jstring jstrError = (*env)->NewStringUTF(env, strerror(-eventResult));
+
+                if (iocbp->data != NULL) {
+                    (*env)->CallVoidMethod(env, (jobject)(iocbp->data), errorMethod, (jint)(-eventResult), jstrError);
+                }
+            }
+
+            jobject obj = (jobject)iocbp->data;
+            putIOCB(theControl, iocbp);
+
+            if (obj != NULL) {
+                (*env)->CallVoidMethod(env, theControl->thisObject, libaioContextDone,obj);
+                // We delete the globalRef after the completion of the callback
+                (*env)->DeleteGlobalRef(env, obj);
+            }
+
+        }
+    }
+
+    pthread_mutex_unlock(&(theControl->pollLock));
+
+}
+
+JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_poll
+  (JNIEnv * env, jobject obj, jobject contextPointer, jobjectArray callbacks, jint min, jint max) {
+    int i = 0;
+    struct io_control * theControl = getIOControl(env, contextPointer);
+    if (theControl == NULL) {
+      return 0;
+    }
+
+
+    int result = io_getevents(theControl->ioContext, min, max, theControl->events, 0);
+    int retVal = result;
+
+    for (i = 0; i < result; i++) {
+        struct io_event * event = &(theControl->events[i]);
+        struct iocb * iocbp = event->obj;
+        int eventResult = (int)event->res;
+
+        #ifdef DEBUG
+            fprintf (stdout, "Poll res: %d totalRes=%d\n", eventResult, result);
+        #endif
+
+        if (eventResult < 0) {
+            #ifdef DEBUG
+                fprintf (stdout, "Error: %s\n", strerror(-eventResult));
+            #endif
+
+            jstring jstrError = (*env)->NewStringUTF(env, strerror(-eventResult));
+
+            (*env)->CallVoidMethod(env, (jobject)(iocbp->data), errorMethod, (jint)(-eventResult), jstrError);
+        }
+
+        (*env)->SetObjectArrayElement(env, callbacks, i, (jobject)iocbp->data);
+
+        if (iocbp->data != NULL) {
+            // We delete the globalRef after the completion of the callback
+            (*env)->DeleteGlobalRef(env, (jobject)iocbp->data);
+        }
+
+        putIOCB(theControl, iocbp);
+    }
+
+    return retVal;
+}
+
+JNIEXPORT jobject JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_newAlignedBuffer
+(JNIEnv * env, jclass clazz, jint size, jint alignment) {
+    if (size % alignment != 0) {
+        throwRuntimeException(env, "Buffer size needs to be aligned to passed argument");
+        return NULL;
+    }
+
+    // This will allocate a buffer, aligned by alignment.
+    // Buffers created here need to be manually destroyed by destroyBuffer, or this would leak on the process heap away of Java's GC managed memory
+    // NOTE: this buffer will contain non initialized data, you must fill it up properly
+    void * buffer;
+    int result = posix_memalign(&buffer, (size_t)alignment, (size_t)size);
+
+    if (result) {
+        throwRuntimeExceptionErrorNo(env, "Can't allocate posix buffer:", result);
+        return NULL;
+    }
+
+    memset(buffer, 0, (size_t)size);
+
+    return (*env)->NewDirectByteBuffer(env, buffer, size);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_freeBuffer
+  (JNIEnv * env, jclass clazz, jobject jbuffer) {
+    if (jbuffer == NULL)
+    {
+       throwRuntimeException(env, "Null pointer");
+       return;
+    }
+  	void *  buffer = (*env)->GetDirectBufferAddress(env, jbuffer);
+  	free(buffer);
+}
+
+
+/** It does nothing... just return true to make sure it has all the binary dependencies */
+JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_getNativeVersion
+  (JNIEnv * env, jclass clazz)
+
+{
+     return org_apache_activemq_artemis_jlibaio_LibaioContext_EXPECTED_NATIVE_VERSION;
+}
+
+JNIEXPORT jlong JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_getSize
+  (JNIEnv * env, jclass clazz, jint fd)
+{
+	struct stat statBuffer;
+
+	if (fstat(fd, &statBuffer) < 0)
+	{
+	    throwIOExceptionErrorNo(env, "Cannot determine file size:", errno);
+		return -1l;
+	}
+	return statBuffer.st_size;
+}
+
+JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_getBlockSizeFD
+  (JNIEnv * env, jclass clazz, jint fd)
+{
+	struct stat statBuffer;
+
+	if (fstat(fd, &statBuffer) < 0)
+	{
+	    throwIOExceptionErrorNo(env, "Cannot determine file size:", errno);
+		return -1l;
+	}
+	return statBuffer.st_blksize;
+}
+
+JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_getBlockSize
+  (JNIEnv * env, jclass clazz, jstring path)
+{
+    const char* f_path = (*env)->GetStringUTFChars(env, path, 0);
+	struct stat statBuffer;
+
+	if (stat(f_path, &statBuffer) < 0)
+	{
+	    throwIOExceptionErrorNo(env, "Cannot determine file size:", errno);
+		return -1l;
+	}
+
+    (*env)->ReleaseStringUTFChars(env, path, f_path);
+
+	return statBuffer.st_blksize;
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_fallocate
+  (JNIEnv * env, jclass clazz, jint fd, jlong size)
+{
+    if (fallocate(fd, 0, 0, (off_t) size) < 0)
+    {
+        throwIOExceptionErrorNo(env, "Could not preallocate file", errno);
+    }
+    fsync(fd);
+    lseek (fd, 0, SEEK_SET);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_fill
+  (JNIEnv * env, jclass clazz, jint fd, jlong size)
+{
+	void * preAllocBuffer = 0;
+	if (posix_memalign(&preAllocBuffer, 512, size) != 0)
+	{
+	      throwOutOfMemoryError(env);
+	      return;
+	}
+	memset(preAllocBuffer, 0, size);
+    lseek (fd, 0, SEEK_SET);
+    write(fd, preAllocBuffer, size);
+	lseek (fd, 0, SEEK_SET);
+	free (preAllocBuffer);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_memsetBuffer
+  (JNIEnv *env, jclass clazz, jobject jbuffer, jint size)
+{
+    #ifdef DEBUG
+        fprintf (stdout, "Mem setting buffer with %d bytes\n", size);
+    #endif
+    void * buffer = (*env)->GetDirectBufferAddress(env, jbuffer);
+
+    if (buffer == 0)
+    {
+        throwRuntimeException(env, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
+        return;
+    }
+
+    memset(buffer, 0, (size_t)size);
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/core/libaio/Native.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/core/libaio/Native.java b/artemis-native/src/main/java/org/apache/activemq/artemis/core/libaio/Native.java
deleted file mode 100644
index 51f5da7..0000000
--- a/artemis-native/src/main/java/org/apache/activemq/artemis/core/libaio/Native.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.activemq.artemis.core.libaio;
-
-import java.nio.ByteBuffer;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-
-public class Native
-{
-   // Functions used for locking files .....
-   public static native int openFile(String fileName);
-
-   public static native void closeFile(int handle);
-
-   public static native boolean flock(int handle);
-   // Functions used for locking files ^^^^^^^^
-
-   public static native void resetBuffer(ByteBuffer directByteBuffer, int size);
-
-   public static native void destroyBuffer(ByteBuffer buffer);
-
-   public static native ByteBuffer newNativeBuffer(long size);
-
-   public static native void newInit(Class someClass);
-
-   public static native ByteBuffer init(Class controllerClass, String fileName, int maxIO, Object logger) throws ActiveMQException;
-
-   public static native long size0(ByteBuffer handle);
-
-   public static native void write(Object thisObject, ByteBuffer handle,
-                             long sequence,
-                             long position,
-                             long size,
-                             ByteBuffer buffer,
-                             Object aioPackageCallback) throws ActiveMQException;
-
-   /** a direct write to the file without the use of libaio's submit. */
-   public static native void writeInternal(ByteBuffer handle, long positionToWrite, long size, ByteBuffer bytes) throws ActiveMQException;
-
-   /**
-    *This is using org.apache.activemq.artemis.core.asyncio.AIOCallback
-     */
-   public static native void read(Object thisObject, ByteBuffer handle, long position, long size, ByteBuffer buffer, Object aioPackageCallback) throws ActiveMQException;
-
-   public static native void fill(ByteBuffer handle, long position, int blocks, long size, byte fillChar) throws ActiveMQException;
-
-   public static native void closeInternal(ByteBuffer handler);
-
-   public static native void stopPoller(ByteBuffer handler);
-
-   /** A native method that does nothing, and just validate if the ELF dependencies are loaded and on the correct platform as this binary format */
-   public static native int getNativeVersion();
-
-   /** Poll asynchronous events from internal queues */
-   public static native void internalPollEvents(ByteBuffer handler);
-
-   // Inner classes ---------------------------------------------------------------------
-
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java
new file mode 100644
index 0000000..8b45f54
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java
@@ -0,0 +1,446 @@
+/*
+ * 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.activemq.artemis.jlibaio;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static io.netty.util.internal.ObjectUtil.checkNotNull;
+
+/**
+ * This class is used as an aggregator for the {@link LibaioFile}.
+ * <br>
+ * It holds native data, and it will share a libaio queue that can be used by multiple files.
+ * <br>
+ * You need to use the poll methods to read the result of write and read submissions.
+ * <br>
+ * You also need to use the special buffer created by {@link LibaioFile} as you need special alignments
+ * when dealing with O_DIRECT files.
+ * <br>
+ * A Single controller can server multiple files. There's no need to create one controller per file.
+ * <br>
+ * <a href="https://ext4.wiki.kernel.org/index.php/Clarifying_Direct_IO's_Semantics">Interesting reading for this.</a>
+ */
+public class LibaioContext <Callback extends SubmitInfo> implements Closeable
+{
+
+   private static final AtomicLong totalMaxIO = new AtomicLong(0);
+
+   /**
+    * This definition needs to match Version.h on the native sources.
+    * <br>
+    * Or else the native module won't be loaded because of version mismatches
+    */
+   private static final int EXPECTED_NATIVE_VERSION = 1;
+
+   private static boolean loaded = false;
+
+   public static boolean isLoaded()
+   {
+      return loaded;
+   }
+
+   private static boolean loadLibrary(final String name)
+   {
+      try
+      {
+         System.loadLibrary(name);
+         if (getNativeVersion() != EXPECTED_NATIVE_VERSION)
+         {
+            NativeLogger.LOGGER.incompatibleNativeLibrary();
+            return false;
+         }
+         else
+         {
+            return true;
+         }
+      }
+      catch (Throwable e)
+      {
+         NativeLogger.LOGGER.debug(name + " -> error loading the native library", e);
+         return false;
+      }
+
+   }
+
+   static
+   {
+      String[] libraries = new String[]{"artemis-native-64", "artemis-native-32"};
+
+      for (String library : libraries)
+      {
+         if (loadLibrary(library))
+         {
+            loaded = true;
+            break;
+         }
+         else
+         {
+            NativeLogger.LOGGER.debug("Library " + library + " not found!");
+         }
+      }
+
+      if (!loaded)
+      {
+         NativeLogger.LOGGER.debug("Couldn't locate LibAIO Wrapper");
+      }
+   }
+
+   /**
+    * This is used to validate leaks on tests.
+    * @return the number of allocated aio, to be used on test checks.
+    */
+   public static long getTotalMaxIO()
+   {
+      return totalMaxIO.get();
+   }
+
+   /**
+    * It will reset all the positions on the buffer to 0, using memset.
+    * @param buffer a native buffer.
+s    */
+   public void memsetBuffer(ByteBuffer buffer)
+   {
+      memsetBuffer(buffer, buffer.limit());
+   }
+
+   /**
+    * This is used on tests validating for leaks.
+    */
+   public static void resetMaxAIO()
+   {
+      totalMaxIO.set(0);
+   }
+
+   /**
+    * the native ioContext including the structure created.
+    */
+   private final ByteBuffer ioContext;
+
+   private final AtomicBoolean closed = new AtomicBoolean(false);
+
+   final Semaphore ioSpace;
+
+   final int queueSize;
+
+   /**
+    * The queue size here will use resources defined on the kernel parameter
+    * <a href="https://www.kernel.org/doc/Documentation/sysctl/fs.txt">fs.aio-max-nr</a> .
+    *
+    * @param queueSize the size to be initialize on libaio
+    *                  io_queue_init which can't be higher than /proc/sys/fs/aio-max-nr.
+    * @param useSemaphore should block on a semaphore avoiding using more submits than what's available.
+    */
+   public LibaioContext(int queueSize, boolean useSemaphore)
+   {
+      try
+      {
+         this.ioContext = newContext(queueSize);
+      }
+      catch (Exception e)
+      {
+         throw e;
+      }
+      this.queueSize = queueSize;
+      totalMaxIO.addAndGet(queueSize);
+      if (useSemaphore)
+      {
+         this.ioSpace = new Semaphore(queueSize);
+      }
+      else
+      {
+         this.ioSpace = null;
+      }
+   }
+
+
+   /**
+    * Documented at {@link LibaioFile#write(long, int, java.nio.ByteBuffer, SubmitInfo)}
+    * @param fd the file descriptor
+    * @param position the write position
+    * @param size number of bytes to use
+    * @param bufferWrite the native buffer
+    * @param callback a callback
+    * @throws IOException in case of error
+    */
+   public void submitWrite(int fd,long position, int size,
+                              ByteBuffer bufferWrite, Callback callback) throws IOException
+   {
+      try
+      {
+         if (ioSpace != null)
+         {
+            ioSpace.acquire();
+         }
+      }
+      catch (InterruptedException e)
+      {
+         Thread.currentThread().interrupt();
+         throw new IOException(e.getMessage(), e);
+      }
+      submitWrite(fd, this.ioContext, position, size, bufferWrite, callback);
+   }
+
+   public void submitRead(int fd, long position, int size, ByteBuffer bufferWrite,
+                          Callback callback) throws IOException
+   {
+      try
+      {
+         if (ioSpace != null)
+         {
+            ioSpace.acquire();
+         }
+      }
+      catch (InterruptedException e)
+      {
+         Thread.currentThread().interrupt();
+         throw new IOException(e.getMessage(), e);
+      }
+      submitRead(fd, this.ioContext, position, size, bufferWrite, callback);
+   }
+
+
+   /**
+    * This is used to close the libaio queues and cleanup the native data used.
+    * <br>
+    * It is unsafe to close the controller while you have pending writes or files open as
+    * this could cause core dumps or VM crashes.
+    */
+   @Override
+   public void close()
+   {
+      if (!closed.getAndSet(true))
+      {
+         totalMaxIO.addAndGet(-queueSize);
+
+         if (ioContext != null)
+         {
+            deleteContext(ioContext);
+         }
+      }
+   }
+
+   @Override
+   protected void finalize() throws Throwable
+   {
+      super.finalize();
+      close();
+   }
+
+   /**
+    * It will open a file. If you set the direct flag = false then you won't need to use the special buffer.
+    * Notice: This will create an empty file if the file doesn't already exist.
+    *
+    * @param file the file to be open.
+    * @param direct will set ODIRECT.
+    * @return It will return a LibaioFile instance.
+    * @throws IOException in case of error.
+    */
+   public LibaioFile<Callback> openFile(File file, boolean direct) throws IOException
+   {
+      return openFile(file.getPath(), direct);
+   }
+
+   /**
+    * It will open a file. If you set the direct flag = false then you won't need to use the special buffer.
+    * Notice: This will create an empty file if the file doesn't already exist.
+    *
+    * @param file the file to be open.
+    * @param direct should use O_DIRECT when opening the file.
+    * @return a new open file.
+    * @throws IOException in case of error.
+    */
+   public LibaioFile<Callback> openFile(String file, boolean direct) throws IOException
+   {
+      checkNotNull(file, "path");
+      checkNotNull(ioContext, "IOContext");
+
+      // note: the native layer will throw an IOException in case of errors
+      int res = LibaioContext.open(file, direct);
+
+      return new LibaioFile<>(res, this);
+   }
+
+   /**
+    * It will open a file disassociated with any sort of factory.
+    * This is useful when you won't use reading / writing through libaio like locking files.
+    * @param file a file name
+    * @param direct will use O_DIRECT
+    * @return a new file
+    * @throws IOException in case of error.
+    */
+   public static LibaioFile openControlFile(String file, boolean direct) throws IOException
+   {
+      checkNotNull(file, "path");
+
+      // note: the native layer will throw an IOException in case of errors
+      int res = LibaioContext.open(file, direct);
+
+      return new LibaioFile<>(res, null);
+   }
+
+   /**
+    * It will poll the libaio queue for results. It should block until min is reached
+    * Results are placed on the callback.
+    * <br>
+    * This shouldn't be called concurrently. You should provide your own synchronization if you need more than one
+    * Thread polling for any reason.
+    * <br>
+    * Notice that the native layer will invoke {@link SubmitInfo#onError(int, String)} in case of failures,
+    *     but it won't call done method for you.
+    *
+    * @param callbacks area to receive the callbacks passed on submission.The size of this callback has to
+    *                  be greater than the parameter max.
+    * @param min       the minimum number of elements to receive. It will block until this is achieved.
+    * @param max       The maximum number of elements to receive.
+    * @return Number of callbacks returned.
+    * @see LibaioFile#write(long, int, java.nio.ByteBuffer, SubmitInfo)
+    * @see LibaioFile#read(long, int, java.nio.ByteBuffer, SubmitInfo)
+    */
+   public int poll(Callback[] callbacks, int min, int max)
+   {
+      int released = poll(ioContext, callbacks, min, max);
+      if (ioSpace != null)
+      {
+         if (released > 0)
+         {
+            ioSpace.release(released);
+         }
+      }
+      return  released;
+   }
+
+   /**
+    * It will start polling and will keep doing until the context is closed.
+    * This will call callbacks on {@link SubmitInfo#onError(int, String)} and
+    *  {@link SubmitInfo#done()}.
+    * In case of error, both {@link SubmitInfo#onError(int, String)} and
+    *   {@link SubmitInfo#done()} are called.
+    */
+   public void poll()
+   {
+      blockedPoll(ioContext);
+   }
+
+   /** Called from the native layer */
+   private void done(SubmitInfo info)
+   {
+      if (ioSpace != null)
+      {
+         ioSpace.release();
+      }
+      info.done();
+   }
+
+   /**
+    * This is the queue for libaio, initialized with queueSize.
+    */
+   private native ByteBuffer newContext(int queueSize);
+
+   /**
+    * Internal method to be used when closing the controller.
+    */
+   private native void deleteContext(ByteBuffer buffer);
+
+   /**
+    * it will return a file descriptor.
+    *
+    * @param path the file name.
+    * @param direct translates as O_DIRECT On open
+    * @return a fd from open C call.
+    */
+   public static native int open(String path, boolean direct);
+
+   static native void close(int fd);
+
+   /**
+    */
+
+   /**
+    * Buffers for O_DIRECT need to use posix_memalign.
+    * <br>
+    * Documented at {@link LibaioFile#newBuffer(int)}.
+    *
+    * @param size needs to be % alignment
+    * @param alignment the alignment used at the dispositive
+    * @return a new native buffer used with posix_memalign
+    */
+   public static native ByteBuffer newAlignedBuffer(int size, int alignment);
+
+   /**
+    * This will call posix free to release the inner buffer allocated at {@link #newAlignedBuffer(int, int)}.
+    * @param buffer a native buffer allocated with {@link #newAlignedBuffer(int, int)}.
+    */
+   public static native void freeBuffer(ByteBuffer buffer);
+
+   /**
+    * Documented at {@link LibaioFile#write(long, int, java.nio.ByteBuffer, SubmitInfo)}.
+    */
+   native void submitWrite(int fd,
+                              ByteBuffer libaioContext,
+                              long position, int size, ByteBuffer bufferWrite,
+                              Callback callback) throws IOException;
+
+   /**
+    * Documented at {@link LibaioFile#read(long, int, java.nio.ByteBuffer, SubmitInfo)}.
+    */
+   native void submitRead(int fd,
+                             ByteBuffer libaioContext,
+                             long position, int size, ByteBuffer bufferWrite,
+                             Callback callback) throws IOException;
+
+   /**
+    * Note: this shouldn't be done concurrently.
+    * This method will block until the min condition is satisfied on the poll.
+    * <p/>
+    * The callbacks will include the original callback sent at submit (read or write).
+    */
+   native int poll(ByteBuffer libaioContext, Callback[] callbacks, int min, int max);
+
+   /**
+    * This method will block as long as the context is open.
+    */
+   native void blockedPoll(ByteBuffer libaioContext);
+
+   static native int getNativeVersion();
+
+   public static native boolean lock(int fd);
+
+   public static native void memsetBuffer(ByteBuffer buffer, int size);
+
+   static native long getSize(int fd);
+
+   static native int getBlockSizeFD(int fd);
+
+   public static int getBlockSize(File path)
+   {
+      return getBlockSize(path.getAbsolutePath());
+   }
+
+   public static native int getBlockSize(String path);
+
+   static native void fallocate(int fd, long size);
+
+   static native void fill(int fd, long size);
+
+   static native void writeInternal(int fd, long position, long size, ByteBuffer bufferWrite) throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioFile.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioFile.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioFile.java
new file mode 100644
index 0000000..bf88d65
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioFile.java
@@ -0,0 +1,152 @@
+/*
+ * 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.activemq.artemis.jlibaio;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * This is an extension to use libaio.
+ */
+public final class LibaioFile<Callback extends SubmitInfo>
+{
+   protected boolean open;
+   /**
+    * This represents a structure allocated on the native
+    * this is a io_context_t
+    */
+   final LibaioContext<Callback> ctx;
+
+   private int fd;
+
+   LibaioFile(int fd, LibaioContext ctx)
+   {
+      this.ctx = ctx;
+      this.fd = fd;
+   }
+
+   public int getBlockSize()
+   {
+      return 512;
+      // FIXME
+      //return LibaioContext.getBlockSizeFD(fd);
+   }
+
+   public boolean lock()
+   {
+      return LibaioContext.lock(fd);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void close() throws IOException
+   {
+      open = false;
+      LibaioContext.close(fd);
+   }
+
+   /**
+    * @return The size of the file.
+    */
+   public long getSize()
+   {
+      return LibaioContext.getSize(fd);
+   }
+
+   /**
+    * It will submit a write to the queue. The callback sent here will be received on the
+    * {@link LibaioContext#poll(SubmitInfo[], int, int)}
+    * In case of the libaio queue is full (e.g. returning E_AGAIN) this method will return false.
+    * <br>
+    * Notice: this won't hold a global reference on buffer, callback should hold a reference towards bufferWrite.
+    * And don't free the buffer until the callback was called as this could crash the VM.
+    *
+    * @param position The position on the file to write. Notice this has to be a multiple of 512.
+    * @param size     The size of the buffer to use while writing.
+    * @param buffer   if you are using O_DIRECT the buffer here needs to be allocated by {@link #newBuffer(int)}.
+    * @param callback A callback to be returned on the poll method.
+    * @throws java.io.IOException in case of error
+    */
+   public void write(long position, int size, ByteBuffer buffer, Callback callback) throws IOException
+   {
+      ctx.submitWrite(fd, position, size, buffer, callback);
+   }
+
+   /**
+    * It will submit a read to the queue. The callback sent here will be received on the
+    * {@link LibaioContext#poll(SubmitInfo[], int, int)}.
+    * In case of the libaio queue is full (e.g. returning E_AGAIN) this method will return false.
+    * <br>
+    * Notice: this won't hold a global reference on buffer, callback should hold a reference towards bufferWrite.
+    * And don't free the buffer until the callback was called as this could crash the VM.
+    * *
+    *
+    * @param position The position on the file to read. Notice this has to be a multiple of 512.
+    * @param size     The size of the buffer to use while reading.
+    * @param buffer   if you are using O_DIRECT the buffer here needs to be allocated by {@link #newBuffer(int)}.
+    * @param callback A callback to be returned on the poll method.
+    * @throws java.io.IOException in case of error
+    * @see LibaioContext#poll(SubmitInfo[], int, int)
+    */
+   public void read(long position, int size, ByteBuffer buffer, Callback callback) throws IOException
+   {
+      ctx.submitRead(fd, position, size, buffer, callback);
+   }
+
+   /**
+    * It will allocate a buffer to be used on libaio operations.
+    * Buffers here are allocated with posix_memalign.
+    * <br>
+    * You need to explicitly free the buffer created from here using the
+    * {@link LibaioContext#freeBuffer(java.nio.ByteBuffer)}.
+    *
+    * @param size the size of the buffer.
+    * @return the buffer allocated.
+    */
+   public ByteBuffer newBuffer(int size)
+   {
+      return LibaioContext.newAlignedBuffer(size, 512);
+   }
+
+   /**
+    * It will preallocate the file with a given size.
+    * @param size number of bytes to be filled on the file
+    */
+   public void fill(long size)
+   {
+      try
+      {
+         LibaioContext.fill(fd, size);
+      }
+      catch (OutOfMemoryError e)
+      {
+         NativeLogger.LOGGER.debug("Didn't have enough memory to allocate " + size + " bytes in memory, using simple fallocate");
+         LibaioContext.fallocate(fd, size);
+      }
+   }
+
+   /**
+    * It will use fallocate to initialize a file.
+    * @param size number of bytes to be filled on the file
+    */
+   public void fallocate(long size)
+   {
+      LibaioContext.fallocate(fd, size);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/NativeLogger.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/NativeLogger.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/NativeLogger.java
new file mode 100644
index 0000000..449c168
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/NativeLogger.java
@@ -0,0 +1,51 @@
+/*
+ * 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.activemq.artemis.jlibaio;
+
+import org.jboss.logging.BasicLogger;
+import org.jboss.logging.Logger;
+import org.jboss.logging.annotations.LogMessage;
+import org.jboss.logging.annotations.Message;
+import org.jboss.logging.annotations.MessageLogger;
+
+/**
+ * Logger Code 14
+ *
+ * each message id must be 6 digits long starting with 14, the 3rd digit donates the level so
+ *
+ * INF0  1
+ * WARN  2
+ * DEBUG 3
+ * ERROR 4
+ * TRACE 5
+ * FATAL 6
+ *
+ * so an INFO message would be 1000 to 6000
+ */
+@MessageLogger(projectCode = "jlibaio")
+public interface NativeLogger extends BasicLogger
+{
+   /**
+    * The journal logger.
+    */
+   NativeLogger LOGGER = Logger.getMessageLogger(NativeLogger.class, NativeLogger.class.getPackage().getName());
+
+
+   @LogMessage(level = Logger.Level.WARN)
+   @Message(id = 1001, value = "You have a native library with a different version than expected", format = Message.Format.MESSAGE_FORMAT)
+   void incompatibleNativeLibrary();
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/SubmitInfo.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/SubmitInfo.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/SubmitInfo.java
new file mode 100644
index 0000000..47feea8
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/SubmitInfo.java
@@ -0,0 +1,25 @@
+/*
+ * 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.activemq.artemis.jlibaio;
+
+public interface SubmitInfo
+{
+   void onError(int errno, String message);
+
+   void done();
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/package-info.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/package-info.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/package-info.java
new file mode 100644
index 0000000..341fa1c
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/**
+ * This packages handles Linux libaio at a low level.
+ * <br>
+ * Buffers needs to be specially allocated by {@link org.apache.activemq.artemis.jlibaio.LibaioContext#newAlignedBuffer(int, int)}
+ * as they need to be aligned to 512 or 4096 when using Direct files.
+ */
+package org.apache.activemq.artemis.jlibaio;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/util/CallbackCache.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/util/CallbackCache.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/util/CallbackCache.java
new file mode 100644
index 0000000..ec2a630
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/util/CallbackCache.java
@@ -0,0 +1,93 @@
+/**
+ * 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.activemq.artemis.jlibaio.util;
+
+
+import org.apache.activemq.artemis.jlibaio.SubmitInfo;
+
+/**
+ * this is an utility class where you can reuse Callbackk objects for your LibaioContext usage.
+ */
+public class CallbackCache<Callback extends SubmitInfo>
+{
+   private final SubmitInfo[] pool;
+
+   private int put = 0;
+   private int get = 0;
+   private int available = 0;
+   private final int size;
+
+   private final Object lock = new Object();
+
+   public CallbackCache(int size)
+   {
+      this.pool = new SubmitInfo[size];
+      this.size = size;
+   }
+
+   public Callback get()
+   {
+      synchronized (lock)
+      {
+         if (available <= 0)
+         {
+            return null;
+         }
+         else
+         {
+            Callback retValue = (Callback)pool[get];
+            pool[get] = null;
+            if (retValue == null)
+            {
+               throw new NullPointerException("You should initialize the pool before using it");
+            }
+            if (retValue != null)
+            {
+               available--;
+               get++;
+               if (get >= size)
+               {
+                  get = 0;
+               }
+            }
+            return retValue;
+         }
+      }
+   }
+
+   public CallbackCache put(Callback callback)
+   {
+      if (callback == null)
+      {
+         return null;
+      }
+      synchronized (lock)
+      {
+         if (available < size)
+         {
+            available++;
+            pool[put++] = callback;
+            if (put >= size)
+            {
+               put = 0;
+            }
+         }
+      }
+      return this;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/CallbackCachelTest.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/CallbackCachelTest.java b/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/CallbackCachelTest.java
new file mode 100644
index 0000000..f62f8e2
--- /dev/null
+++ b/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/CallbackCachelTest.java
@@ -0,0 +1,112 @@
+/**
+ * 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.activemq.artemis.jlibaio.test;
+
+import java.util.HashSet;
+
+import org.apache.activemq.artemis.jlibaio.util.CallbackCache;
+import org.apache.activemq.artemis.jlibaio.SubmitInfo;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CallbackCachelTest
+{
+   @Test
+   public void testPartiallyInitialized()
+   {
+      CallbackCache<MyPool> pool = new CallbackCache(100);
+
+
+      for (int i = 0; i < 50; i++)
+      {
+         pool.put(new MyPool(i));
+      }
+
+      MyPool value = pool.get();
+
+      Assert.assertNotNull(value);
+
+      pool.put(value);
+
+
+      // add and remove immediately
+      for (int i = 0; i < 777; i++)
+      {
+         pool.put(pool.get());
+      }
+
+
+      HashSet<MyPool> hashValues = new HashSet<>();
+
+
+      MyPool getValue;
+      while ((getValue = pool.get()) != null)
+      {
+         hashValues.add(getValue);
+      }
+
+
+      Assert.assertEquals(50, hashValues.size());
+   }
+
+   static class MyPool implements SubmitInfo
+   {
+      public final int i;
+
+      MyPool(int i)
+      {
+         this.i = i;
+      }
+
+
+      public int getI()
+      {
+         return i;
+      }
+
+      @Override
+      public void onError(int errno, String message)
+      {
+      }
+
+      @Override
+      public void done()
+      {
+
+      }
+
+      @Override
+      public boolean equals(Object o)
+      {
+         if (this == o) return true;
+         if (o == null || getClass() != o.getClass()) return false;
+
+         MyPool myPool = (MyPool) o;
+
+         if (i != myPool.i) return false;
+
+         return true;
+      }
+
+      @Override
+      public int hashCode()
+      {
+         return i;
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/LibaioTest.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/LibaioTest.java b/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/LibaioTest.java
new file mode 100644
index 0000000..e46caf3
--- /dev/null
+++ b/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/LibaioTest.java
@@ -0,0 +1,859 @@
+/*
+ * 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.activemq.artemis.jlibaio.test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
+import org.apache.activemq.artemis.jlibaio.SubmitInfo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * This test is using a different package from {@link LibaioFile}
+ * as I need to validate public methods on the API
+ */
+public class LibaioTest
+{
+
+   @BeforeClass
+   public static void testAIO()
+   {
+      Assume.assumeTrue(LibaioContext.isLoaded());
+   }
+
+   /** This is just an arbitrary number for a number of elements you need to pass to the libaio init method
+    * Some of the tests are using half of this number, so if anyone decide to change this please use an even number.
+    */
+   private static final int LIBAIO_QUEUE_SIZE = 50;
+
+   @Rule
+   public TemporaryFolder temporaryFolder;
+
+   public LibaioContext<TestInfo> control;
+
+   @Before
+   public void setUpFactory()
+   {
+      control = new LibaioContext<>(LIBAIO_QUEUE_SIZE, true);
+   }
+
+   @After
+   public void deleteFactory()
+   {
+      control.close();
+      validateLibaio();
+   }
+
+   public void validateLibaio()
+   {
+      Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
+   }
+
+   public LibaioTest()
+   {
+        /*
+         *  I didn't use /tmp for three reasons
+         *  - Most systems now will use tmpfs which is not compatible with O_DIRECT
+         *  - This would fill up /tmp in case of failures.
+         *  - target is cleaned up every time you do a mvn clean, so it's safer
+         */
+      File parent = new File("./target");
+      parent.mkdirs();
+      temporaryFolder = new TemporaryFolder(parent);
+   }
+
+   @Test
+   public void testOpen() throws Exception
+   {
+      LibaioFile fileDescriptor = control.openFile(temporaryFolder.newFile("test.bin"), true);
+      fileDescriptor.close();
+   }
+
+   @Test
+   public void testInitAndFallocate() throws Exception
+   {
+      LibaioFile fileDescriptor = control.openFile(temporaryFolder.newFile("test.bin"), true);
+      fileDescriptor.fallocate(1024 * 1024);
+
+      ByteBuffer buffer = fileDescriptor.newBuffer(1024 * 1024);
+      fileDescriptor.read(0, 1024 * 1024, buffer, new TestInfo());
+
+      TestInfo[] callbacks = new TestInfo[1];
+      control.poll(callbacks, 1, 1);
+
+      fileDescriptor.close();
+
+
+      buffer.position(0);
+
+      LibaioFile fileDescriptor2 = control.openFile(temporaryFolder.newFile("test2.bin"), true);
+      fileDescriptor2.fill(1024 * 1024);
+      fileDescriptor2.read(0, 1024 * 1024, buffer, new TestInfo());
+
+      control.poll(callbacks, 1, 1);
+      for (int i = 0; i < 1024 * 1024; i++)
+      {
+         Assert.assertEquals(0, buffer.get());
+      }
+
+      LibaioContext.freeBuffer(buffer);
+   }
+
+   @Test
+   public void testSubmitWriteOnTwoFiles() throws Exception
+   {
+
+      File file1 = temporaryFolder.newFile("test.bin");
+      File file2 = temporaryFolder.newFile("test2.bin");
+
+      fillupFile(file1, LIBAIO_QUEUE_SIZE / 2);
+      fillupFile(file2, LIBAIO_QUEUE_SIZE / 2);
+
+      LibaioFile[] fileDescriptor = new LibaioFile[]{control.openFile(file1, true),
+         control.openFile(file2, true)};
+
+      Assert.assertEquals((LIBAIO_QUEUE_SIZE / 2) * 512, fileDescriptor[0].getSize());
+      Assert.assertEquals((LIBAIO_QUEUE_SIZE / 2) * 512, fileDescriptor[1].getSize());
+      Assert.assertEquals(fileDescriptor[0].getBlockSize(), fileDescriptor[1].getBlockSize());
+      Assert.assertEquals(LibaioContext.getBlockSize(temporaryFolder.getRoot()), LibaioContext.getBlockSize(file1));
+      Assert.assertEquals(LibaioContext.getBlockSize(file1), LibaioContext.getBlockSize(file2));
+      System.out.println("blockSize = " + fileDescriptor[0].getBlockSize());
+      System.out.println("blockSize /tmp= " + LibaioContext.getBlockSize("/tmp"));
+
+      ByteBuffer buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+      try
+      {
+         for (int i = 0; i < 512; i++)
+         {
+            buffer.put((byte) 'a');
+         }
+
+         TestInfo callback = new TestInfo();
+         TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+         for (int i = 0; i < LIBAIO_QUEUE_SIZE / 2; i++)
+         {
+            for (LibaioFile file : fileDescriptor)
+            {
+               file.write(i * 512, 512, buffer, callback);
+            }
+         }
+
+         Assert.assertEquals(LIBAIO_QUEUE_SIZE, control.poll(callbacks, LIBAIO_QUEUE_SIZE, LIBAIO_QUEUE_SIZE));
+
+         for (Object returnedCallback : callbacks)
+         {
+            Assert.assertSame(returnedCallback, callback);
+         }
+
+         for (LibaioFile file : fileDescriptor)
+         {
+            ByteBuffer bigbuffer = LibaioContext.newAlignedBuffer(512 * 25, 512);
+            file.read(0, 512 * 25, bigbuffer, callback);
+            Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+            for (Object returnedCallback : callbacks)
+            {
+               Assert.assertSame(returnedCallback, callback);
+            }
+
+            for (int i = 0; i < 512 * 25; i++)
+            {
+               Assert.assertEquals((byte) 'a', bigbuffer.get());
+            }
+
+            LibaioContext.freeBuffer(bigbuffer);
+
+            file.close();
+         }
+      }
+      finally
+      {
+         LibaioContext.freeBuffer(buffer);
+      }
+   }
+
+   @Test
+   public void testSubmitWriteAndRead() throws Exception
+   {
+      TestInfo callback = new TestInfo();
+
+      TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+      LibaioFile fileDescriptor = control.openFile(temporaryFolder.newFile("test.bin"), true);
+
+      // ByteBuffer buffer = ByteBuffer.allocateDirect(512);
+      ByteBuffer buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+      try
+      {
+         for (int i = 0; i < 512; i++)
+         {
+            buffer.put((byte) 'a');
+         }
+
+         buffer.rewind();
+
+         fileDescriptor.write(0, 512, buffer, callback);
+
+         int retValue = control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE);
+         Assert.assertEquals(1, retValue);
+
+         Assert.assertSame(callback, callbacks[0]);
+
+         LibaioContext.freeBuffer(buffer);
+
+         buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+         for (int i = 0; i < 512; i++)
+         {
+            buffer.put((byte) 'B');
+         }
+
+         fileDescriptor.write(0, 512, buffer, null);
+
+         Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+         buffer.rewind();
+
+         fileDescriptor.read(0, 512, buffer, null);
+
+         Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+         for (int i = 0; i < 512; i++)
+         {
+            Assert.assertEquals('B', buffer.get());
+         }
+      }
+      finally
+      {
+         LibaioContext.freeBuffer(buffer);
+         fileDescriptor.close();
+      }
+   }
+
+   @Test
+   /**
+    * This file is making use of libaio without O_DIRECT
+    * We won't need special buffers on this case.
+    */
+   public void testSubmitWriteAndReadRegularBuffers() throws Exception
+   {
+      TestInfo callback = new TestInfo();
+
+      TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+      File file = temporaryFolder.newFile("test.bin");
+
+      fillupFile(file, LIBAIO_QUEUE_SIZE);
+
+      LibaioFile fileDescriptor = control.openFile(file, false);
+
+      final int BUFFER_SIZE = 50;
+
+      ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
+
+      try
+      {
+         for (int i = 0; i < BUFFER_SIZE; i++)
+         {
+            buffer.put((byte) 'a');
+         }
+
+         buffer.rewind();
+
+         fileDescriptor.write(0, BUFFER_SIZE, buffer, callback);
+
+         int retValue = control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE);
+         System.out.println("Return from poll::" + retValue);
+         Assert.assertEquals(1, retValue);
+
+         Assert.assertSame(callback, callbacks[0]);
+
+         buffer.rewind();
+
+         for (int i = 0; i < BUFFER_SIZE; i++)
+         {
+            buffer.put((byte) 'B');
+         }
+
+         fileDescriptor.write(0, BUFFER_SIZE, buffer, null);
+
+         Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+         buffer.rewind();
+
+         fileDescriptor.read(0, 50, buffer, null);
+
+         Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+         for (int i = 0; i < BUFFER_SIZE; i++)
+         {
+            Assert.assertEquals('B', buffer.get());
+         }
+      }
+      finally
+      {
+         fileDescriptor.close();
+      }
+   }
+
+   @Test
+   public void testSubmitRead() throws Exception
+   {
+
+      TestInfo callback = new TestInfo();
+
+      TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+      File file = temporaryFolder.newFile("test.bin");
+
+      fillupFile(file, LIBAIO_QUEUE_SIZE);
+
+      LibaioFile fileDescriptor = control.openFile(file, true);
+
+      ByteBuffer buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+      final int BUFFER_SIZE = 512;
+      try
+      {
+         for (int i = 0; i < BUFFER_SIZE; i++)
+         {
+            buffer.put((byte) '@');
+         }
+
+         fileDescriptor.write(0, BUFFER_SIZE, buffer, callback);
+         Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+         Assert.assertSame(callback, callbacks[0]);
+
+         buffer.rewind();
+
+         fileDescriptor.read(0, BUFFER_SIZE, buffer, callback);
+
+         Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+         Assert.assertSame(callback, callbacks[0]);
+
+         for (int i = 0; i < BUFFER_SIZE; i++)
+         {
+            Assert.assertEquals('@', buffer.get());
+         }
+      }
+      finally
+      {
+         LibaioContext.freeBuffer(buffer);
+         fileDescriptor.close();
+      }
+   }
+
+   @Test
+   public void testInvalidWrite() throws Exception
+   {
+
+      TestInfo callback = new TestInfo();
+
+      TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+      File file = temporaryFolder.newFile("test.bin");
+
+      fillupFile(file, LIBAIO_QUEUE_SIZE);
+
+      LibaioFile fileDescriptor = control.openFile(file, true);
+
+      try
+      {
+         ByteBuffer buffer = ByteBuffer.allocateDirect(300);
+         for (int i = 0; i < 300; i++)
+         {
+            buffer.put((byte) 'z');
+         }
+
+         fileDescriptor.write(0, 300, buffer, callback);
+
+         Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+         Assert.assertTrue(callbacks[0].isError());
+
+         // Error condition
+         Assert.assertSame(callbacks[0], callback);
+
+         System.out.println("Error:" + callbacks[0]);
+
+         buffer = fileDescriptor.newBuffer(512);
+         for (int i = 0; i < 512; i++)
+         {
+            buffer.put((byte) 'z');
+         }
+
+         callback = new TestInfo();
+
+         fileDescriptor.write(0, 512, buffer, callback);
+
+         Assert.assertEquals(1, control.poll(callbacks, 1, 1));
+
+         Assert.assertSame(callback, callbacks[0]);
+
+         fileDescriptor.write(5, 512, buffer, callback);
+
+         Assert.assertEquals(1, control.poll(callbacks, 1, 1));
+
+         Assert.assertTrue(callbacks[0].isError());
+
+         callbacks = null;
+         callback = null;
+
+         TestInfo.checkLeaks();
+      }
+      finally
+      {
+         fileDescriptor.close();
+      }
+   }
+
+   @Test
+   public void testLeaks() throws Exception
+   {
+      File file = temporaryFolder.newFile("test.bin");
+
+      fillupFile(file, LIBAIO_QUEUE_SIZE * 2);
+
+      TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+      LibaioFile<TestInfo> fileDescriptor = control.openFile(file, true);
+
+      ByteBuffer bufferWrite = LibaioContext.newAlignedBuffer(512, 512);
+
+      try
+      {
+         for (int i = 0; i < 512; i++)
+         {
+            bufferWrite.put((byte) 'B');
+         }
+
+         for (int j = 0; j < LIBAIO_QUEUE_SIZE * 2; j++)
+         {
+            for (int i = 0; i < LIBAIO_QUEUE_SIZE; i++)
+            {
+               TestInfo countClass = new TestInfo();
+               fileDescriptor.write(i * 512, 512, bufferWrite, countClass);
+            }
+
+            Assert.assertEquals(LIBAIO_QUEUE_SIZE, control.poll(callbacks, LIBAIO_QUEUE_SIZE, LIBAIO_QUEUE_SIZE));
+
+            for (int i = 0; i < LIBAIO_QUEUE_SIZE; i++)
+            {
+               Assert.assertNotNull(callbacks[i]);
+               callbacks[i] = null;
+            }
+         }
+
+         TestInfo.checkLeaks();
+      }
+      finally
+      {
+         LibaioContext.freeBuffer(bufferWrite);
+      }
+   }
+
+   @Test
+   public void testLock() throws Exception
+   {
+      File file = temporaryFolder.newFile("test.bin");
+
+      LibaioFile fileDescriptor = control.openFile(file, true);
+      fileDescriptor.lock();
+
+      fileDescriptor.close();
+   }
+
+   @Test
+   public void testAlloc() throws Exception
+   {
+      File file = temporaryFolder.newFile("test.bin");
+
+      LibaioFile fileDescriptor = control.openFile(file, true);
+      fileDescriptor.fill(10 * 1024 * 1024);
+
+      fileDescriptor.close();
+   }
+
+   @Test
+   public void testReleaseNullBuffer() throws Exception
+   {
+      boolean failed = false;
+      try
+      {
+         LibaioContext.freeBuffer(null);
+      }
+      catch (Exception expected)
+      {
+         failed = true;
+      }
+
+      Assert.assertTrue("Exception happened!", failed);
+
+   }
+
+   @Test
+   public void testMemset() throws Exception
+   {
+
+      ByteBuffer buffer = LibaioContext.newAlignedBuffer(512 * 8, 512);
+
+      for (int i = 0; i < buffer.capacity(); i++)
+      {
+         buffer.put((byte) 'z');
+      }
+
+      buffer.position(0);
+
+      for (int i = 0; i < buffer.capacity(); i++)
+      {
+         Assert.assertEquals((byte) 'z', buffer.get());
+      }
+
+      control.memsetBuffer(buffer);
+
+      buffer.position(0);
+
+      for (int i = 0; i < buffer.capacity(); i++)
+      {
+         Assert.assertEquals((byte) 0, buffer.get());
+      }
+
+      LibaioContext.freeBuffer(buffer);
+
+   }
+
+   @Test
+   public void testIOExceptionConditions() throws Exception
+   {
+      boolean exceptionThrown = false;
+
+      control.close();
+      control = new LibaioContext<>(LIBAIO_QUEUE_SIZE, false);
+      try
+      {
+         // There is no space for a queue this huge, the native layer should throw the exception
+         LibaioContext newController = new LibaioContext(Integer.MAX_VALUE, false);
+      }
+      catch (RuntimeException e)
+      {
+         exceptionThrown = true;
+      }
+
+      Assert.assertTrue(exceptionThrown);
+      exceptionThrown = false;
+
+      try
+      {
+         // this should throw an exception, we shouldn't be able to open a directory!
+         control.openFile(temporaryFolder.getRoot(), true);
+      }
+      catch (IOException expected)
+      {
+         exceptionThrown = true;
+      }
+
+      Assert.assertTrue(exceptionThrown);
+
+      exceptionThrown = false;
+
+      LibaioFile fileDescriptor = control.openFile(temporaryFolder.newFile(), true);
+      fileDescriptor.close();
+      try
+      {
+         fileDescriptor.close();
+      }
+      catch (IOException expected)
+      {
+         exceptionThrown = true;
+      }
+
+      Assert.assertTrue(exceptionThrown);
+
+      fileDescriptor = control.openFile(temporaryFolder.newFile(), true);
+
+      ByteBuffer buffer = fileDescriptor.newBuffer(512);
+
+      try
+      {
+         for (int i = 0; i < 512; i++)
+         {
+            buffer.put((byte) 'a');
+         }
+
+         for (int i = 0; i < LIBAIO_QUEUE_SIZE; i++)
+         {
+            fileDescriptor.write(i * 512, 512, buffer, new TestInfo());
+         }
+
+         boolean ex = false;
+         try
+         {
+            fileDescriptor.write(0, 512, buffer, new TestInfo());
+         }
+         catch (Exception e)
+         {
+            ex = true;
+         }
+
+         Assert.assertTrue(ex);
+
+         TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+         Assert.assertEquals(LIBAIO_QUEUE_SIZE, control.poll(callbacks, LIBAIO_QUEUE_SIZE, LIBAIO_QUEUE_SIZE));
+
+         // it should be possible to write now after queue space being released
+         fileDescriptor.write(0, 512, buffer, new TestInfo());
+         Assert.assertEquals(1, control.poll(callbacks, 1, 100));
+
+         TestInfo errorCallback = new TestInfo();
+         // odd positions will have failures through O_DIRECT
+         fileDescriptor.read(3, 512, buffer, errorCallback);
+         Assert.assertEquals(1, control.poll(callbacks, 1, 50));
+         Assert.assertTrue(callbacks[0].isError());
+         Assert.assertSame(errorCallback, (callbacks[0]));
+
+         // to help GC and the checkLeaks
+         callbacks = null;
+         errorCallback = null;
+
+         TestInfo.checkLeaks();
+
+         exceptionThrown = false;
+         try
+         {
+            LibaioContext.newAlignedBuffer(300, 512);
+         }
+         catch (RuntimeException e)
+         {
+            exceptionThrown = true;
+         }
+
+         Assert.assertTrue(exceptionThrown);
+
+         exceptionThrown = false;
+         try
+         {
+            LibaioContext.newAlignedBuffer(-512, 512);
+         }
+         catch (RuntimeException e)
+         {
+            exceptionThrown = true;
+         }
+
+         Assert.assertTrue(exceptionThrown);
+      }
+      finally
+      {
+         LibaioContext.freeBuffer(buffer);
+      }
+   }
+
+   @Test
+   public void testBlockedCallback() throws Exception
+   {
+      final LibaioContext blockedContext = new LibaioContext(500, true);
+      Thread t = new Thread()
+      {
+         public void run()
+         {
+            blockedContext.poll();
+         }
+      };
+
+      t.start();
+
+
+      int NUMBER_OF_BLOCKS = 5000;
+
+      final CountDownLatch latch = new CountDownLatch(NUMBER_OF_BLOCKS);
+
+      File file = temporaryFolder.newFile("sub-file.txt");
+      LibaioFile aioFile = blockedContext.openFile(file, true);
+      aioFile.fill(NUMBER_OF_BLOCKS * 512);
+
+      final AtomicInteger errors = new AtomicInteger(0);
+
+      class MyCallback implements SubmitInfo
+      {
+         @Override
+         public void onError(int errno, String message)
+         {
+            errors.incrementAndGet();
+         }
+
+         @Override
+         public void done()
+         {
+            latch.countDown();
+         }
+      }
+
+      MyCallback callback = new MyCallback();
+
+      ByteBuffer buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+
+      for (int i = 0; i < 512; i++)
+      {
+         buffer.put((byte)'a');
+      }
+
+      long start = System.currentTimeMillis();
+
+      for (int i = 0; i < NUMBER_OF_BLOCKS; i++)
+      {
+         aioFile.write(i * 512, 512, buffer, callback);
+      }
+
+      long end = System.currentTimeMillis();
+
+      latch.await();
+
+
+      System.out.println("time = " + (end - start) + " writes/second=" + NUMBER_OF_BLOCKS * 1000L / (end - start));
+//
+//      MultiThreadAsynchronousFileTest.debug((sync ? "Sync result:" : "Async result:") + " Records/Second = " +
+//                                               MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS *
+//                                                  MultiThreadAsynchronousFileTest.NUMBER_OF_LINES *
+//                                                  1000 /
+//                                                  (endTime - startTime) +
+//                                               " total time = " +
+//                                               (endTime - startTime) +
+//                                               " total number of records = " +
+//                                               MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS *
+//                                                  MultiThreadAsynchronousFileTest.NUMBER_OF_LINES);
+
+      Thread.sleep(100);
+
+      blockedContext.close();
+      t.join();
+   }
+
+   private void fillupFile(File file, int blocks) throws IOException
+   {
+      FileOutputStream fileOutputStream = new FileOutputStream(file);
+      byte[] bufferWrite = new byte[512];
+      for (int i = 0; i < 512; i++)
+      {
+         bufferWrite[i] = (byte) 0;
+      }
+
+      for (int i = 0; i < blocks; i++)
+      {
+         fileOutputStream.write(bufferWrite);
+      }
+
+      fileOutputStream.close();
+   }
+
+
+   static class TestInfo implements SubmitInfo
+   {
+      static AtomicInteger count = new AtomicInteger();
+
+      @Override
+      protected void finalize() throws Throwable
+      {
+         super.finalize();
+         count.decrementAndGet();
+      }
+
+      public static void checkLeaks() throws InterruptedException
+      {
+         for (int i = 0; count.get() != 0 && i < 50; i++)
+         {
+            WeakReference reference = new WeakReference(new Object());
+            while (reference.get() != null)
+            {
+               System.gc();
+               Thread.sleep(100);
+            }
+         }
+         Assert.assertEquals(0, count.get());
+      }
+
+      boolean error = false;
+      String errorMessage;
+      int errno;
+
+      public TestInfo()
+      {
+         count.incrementAndGet();
+      }
+
+      @Override
+      public void onError(int errno, String message)
+      {
+         this.errno = errno;
+         this.errorMessage = message;
+         this.error = true;
+      }
+
+      @Override
+      public void done()
+      {
+      }
+
+      public int getErrno()
+      {
+         return errno;
+      }
+
+      public void setErrno(int errno)
+      {
+         this.errno = errno;
+      }
+
+      public boolean isError()
+      {
+         return error;
+      }
+
+      public void setError(boolean error)
+      {
+         this.error = error;
+      }
+
+      public String getErrorMessage()
+      {
+         return errorMessage;
+      }
+
+      public void setErrorMessage(String errorMessage)
+      {
+         this.errorMessage = errorMessage;
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
index 71610b4..f74d6d7 100644
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
@@ -20,6 +20,7 @@ package org.apache.activemq.artemis.core.protocol.proton.plug;
 import java.util.concurrent.Executor;
 
 import io.netty.buffer.ByteBuf;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.qpid.proton.amqp.Binary;
 import org.apache.qpid.proton.amqp.transport.AmqpError;
 import org.apache.qpid.proton.amqp.transport.ErrorCondition;
@@ -30,7 +31,6 @@ import org.apache.qpid.proton.jms.EncodedMessage;
 import org.apache.qpid.proton.message.ProtonJMessage;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.protocol.proton.ProtonProtocolManager;
 import org.apache.activemq.artemis.core.server.QueueQueryResult;
 import org.apache.activemq.artemis.core.server.ServerConsumer;
@@ -275,7 +275,7 @@ public class ProtonSessionIntegrationCallback implements AMQPSessionCallback, Se
 
       serverSession.send(message, false);
 
-      manager.getServer().getStorageManager().afterCompleteOperations(new IOAsyncTask()
+      manager.getServer().getStorageManager().afterCompleteOperations(new IOCallback()
       {
          @Override
          public void done()

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java b/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java
index aa3f9e0..45260d5 100644
--- a/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java
+++ b/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java
@@ -22,7 +22,7 @@ import io.netty.buffer.EmptyByteBuf;
 import io.netty.handler.codec.mqtt.MqttMessageType;
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.server.ServerConsumer;
 import org.apache.activemq.artemis.core.server.ServerMessage;
 import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
@@ -183,7 +183,7 @@ public class MQTTPublishManager
 
    private void createMessageAck(final int messageId, final int qos)
    {
-      session.getServer().getStorageManager().afterCompleteOperations(new IOAsyncTask()
+      session.getServer().getStorageManager().afterCompleteOperations(new IOCallback()
       {
          @Override
          public void done()


[2/9] activemq-artemis git commit: ARTEMIS-163 First pass on the native AIO refactoring

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java
index 2dc0d38..e49e50b 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.activemq.artemis.tests.integration.journal;
 
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.junit.BeforeClass;
 
 public class AIOImportExportTest extends NIOImportExportTest
@@ -31,6 +31,6 @@ public class AIOImportExportTest extends NIOImportExportTest
    @Override
    protected SequentialFileFactory getFileFactory() throws Exception
    {
-      return new AIOSequentialFileFactory(getTestDirfile());
+      return new AIOSequentialFileFactory(getTestDirfile(), 10);
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java
index 39972e7..f1ce785 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java
@@ -19,8 +19,8 @@ package org.apache.activemq.artemis.tests.integration.journal;
 import java.io.File;
 
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
 import org.junit.BeforeClass;
 
@@ -43,7 +43,7 @@ public class AIOJournalCompactTest extends NIOJournalCompactTest
 
       return new AIOSequentialFileFactory(getTestDirfile(),
                                           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
-                                          100000,
+                                          100000, 10,
                                           false);
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java
index acbaac4..59f6b95 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java
@@ -17,10 +17,10 @@
 package org.apache.activemq.artemis.tests.integration.journal;
 import java.io.File;
 
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestUnit;
 import org.junit.Assert;
 import org.junit.Before;
@@ -48,7 +48,7 @@ public class AIOJournalImplTest extends JournalImplTestUnit
    public void setUp() throws Exception
    {
       super.setUp();
-      if (!AsynchronousFileImpl.isLoaded())
+      if (!LibaioContext.isLoaded())
       {
          Assert.fail(String.format("libAIO is not loaded on %s %s %s",
                                    System.getProperty("os.name"),
@@ -67,7 +67,7 @@ public class AIOJournalImplTest extends JournalImplTestUnit
       file.mkdir();
 
       return new AIOSequentialFileFactory(getTestDirfile(),
-            JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO, 1000000,
+            JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO, 1000000, 10,
             false);
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java
index 072c820..acc65b1 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java
@@ -19,9 +19,9 @@ import java.io.File;
 import java.nio.ByteBuffer;
 
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.SequentialFileFactoryTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -38,13 +38,13 @@ public class AIOSequentialFileFactoryTest extends SequentialFileFactoryTestBase
    @Override
    protected SequentialFileFactory createFactory(String folder)
    {
-      return new AIOSequentialFileFactory(new File(folder));
+      return new AIOSequentialFileFactory(new File(folder), 10);
    }
 
    @Test
    public void testBuffer() throws Exception
    {
-      SequentialFile file = factory.createSequentialFile("filtetmp.log", 10);
+      SequentialFile file = factory.createSequentialFile("filtetmp.log");
       file.open();
       ByteBuffer buff = factory.newBuffer(10);
       Assert.assertEquals(512, buff.limit());

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java
index 1a69dab..c4b1acc 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java
@@ -19,8 +19,8 @@ package org.apache.activemq.artemis.tests.integration.journal;
 import java.io.File;
 
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 
 public class NIOBufferedJournalCompactTest extends NIOJournalCompactTest
 {
@@ -34,7 +34,7 @@ public class NIOBufferedJournalCompactTest extends NIOJournalCompactTest
 
       file.mkdir();
 
-      return new NIOSequentialFileFactory(getTestDirfile(), true);
+      return new NIOSequentialFileFactory(getTestDirfile(), true, 1);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java
index d581644..e50143a 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java
@@ -17,8 +17,8 @@
 package org.apache.activemq.artemis.tests.integration.journal;
 
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.SimpleEncoding;
 import org.junit.Test;
@@ -32,7 +32,7 @@ public class NIOImportExportTest extends JournalImplTestBase
    @Override
    protected SequentialFileFactory getFileFactory() throws Exception
    {
-      return new NIOSequentialFileFactory(getTestDirfile(), true);
+      return new NIOSequentialFileFactory(getTestDirfile(), true, 1);
    }
 
    // Constants -----------------------------------------------------

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java
index 3e42498..c3148bb 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java
@@ -31,18 +31,18 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.AbstractJournalUpdateTask;
 import org.apache.activemq.artemis.core.journal.impl.JournalCompactor;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.journal.impl.JournalFileImpl;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager;
 import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
 import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
@@ -72,7 +72,7 @@ public class NIOJournalCompactTest extends JournalImplTestBase
 
       for (int i = 0; i < 5; i++)
       {
-         SequentialFile file = fileFactory.createSequentialFile("file-" + i + ".tst", 1);
+         SequentialFile file = fileFactory.createSequentialFile("file-" + i + ".tst");
          dataFiles.add(new JournalFileImpl(file, 0, JournalImpl.FORMAT_VERSION));
       }
 
@@ -80,7 +80,7 @@ public class NIOJournalCompactTest extends JournalImplTestBase
 
       for (int i = 0; i < 3; i++)
       {
-         SequentialFile file = fileFactory.createSequentialFile("file-" + i + ".tst.new", 1);
+         SequentialFile file = fileFactory.createSequentialFile("file-" + i + ".tst.new");
          newFiles.add(new JournalFileImpl(file, 0, JournalImpl.FORMAT_VERSION));
       }
 
@@ -1825,7 +1825,7 @@ public class NIOJournalCompactTest extends JournalImplTestBase
 
                   storage.commit(tx);
 
-                  ctx.executeOnCompletion(new IOAsyncTask()
+                  ctx.executeOnCompletion(new IOCallback()
                   {
                      public void onError(int errorCode, String errorMessage)
                      {
@@ -1939,7 +1939,7 @@ public class NIOJournalCompactTest extends JournalImplTestBase
    @Override
    protected SequentialFileFactory getFileFactory() throws Exception
    {
-      return new NIOSequentialFileFactory(getTestDirfile());
+      return new NIOSequentialFileFactory(getTestDirfile(), 1);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java
index ad7671f..b4ff147 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java
@@ -21,8 +21,8 @@ import java.io.File;
 import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestUnit;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 
 public class NIOJournalImplTest extends JournalImplTestUnit
 {
@@ -39,7 +39,7 @@ public class NIOJournalImplTest extends JournalImplTestUnit
 
       file.mkdir();
 
-      return new NIOSequentialFileFactory(getTestDirfile(), true);
+      return new NIOSequentialFileFactory(getTestDirfile(), true, 1);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java
index 059bf59..d82b28c 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java
@@ -19,8 +19,8 @@ package org.apache.activemq.artemis.tests.integration.journal;
 import java.io.File;
 
 import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestUnit;
 
 public class NIONoBufferJournalImplTest extends JournalImplTestUnit
@@ -38,7 +38,7 @@ public class NIONoBufferJournalImplTest extends JournalImplTestUnit
 
       file.mkdir();
 
-      return new NIOSequentialFileFactory(new File(getTestDir()), false);
+      return new NIOSequentialFileFactory(new File(getTestDir()), false, 1);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java
index 717d03c..2072300 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java
@@ -17,8 +17,8 @@
 package org.apache.activemq.artemis.tests.integration.journal;
 import java.io.File;
 
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.SequentialFileFactoryTestBase;
 
 public class NIONonBufferedSequentialFileFactoryTest extends SequentialFileFactoryTestBase
@@ -27,7 +27,7 @@ public class NIONonBufferedSequentialFileFactoryTest extends SequentialFileFacto
    @Override
    protected SequentialFileFactory createFactory(String folder)
    {
-      return new NIOSequentialFileFactory(new File(folder), false);
+      return new NIOSequentialFileFactory(new File(folder), false, 1);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java
index 1ca667b..bcab8e6 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java
@@ -17,8 +17,8 @@
 package org.apache.activemq.artemis.tests.integration.journal;
 import java.io.File;
 
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.SequentialFileFactoryTestBase;
 
 public class NIOSequentialFileFactoryTest extends SequentialFileFactoryTestBase
@@ -27,7 +27,7 @@ public class NIOSequentialFileFactoryTest extends SequentialFileFactoryTestBase
    @Override
    protected SequentialFileFactory createFactory(String folder)
    {
-      return new NIOSequentialFileFactory(new File(folder), true);
+      return new NIOSequentialFileFactory(new File(folder), true, 1);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java
index 5e8587d..7cebc4f 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java
@@ -20,17 +20,17 @@ import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.util.SpawnedVMSupport;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.journal.LoaderCallback;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -126,7 +126,7 @@ public class ValidateTransactionHealthTest extends ActiveMQTestBase
    {
       try
       {
-         if (type.equals("aio") && !AsynchronousFileImpl.isLoaded())
+         if (type.equals("aio") && !LibaioContext.isLoaded())
          {
             // Using System.out as this output will go towards junit report
             System.out.println("AIO not found, test being ignored on this platform");
@@ -381,15 +381,16 @@ public class ValidateTransactionHealthTest extends ActiveMQTestBase
          return new AIOSequentialFileFactory(new File(directory),
                                              JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
                                              JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
+                                             10,
                                              false);
       }
       else if (factoryType.equals("nio2"))
       {
-         return new NIOSequentialFileFactory(new File(directory), true);
+         return new NIOSequentialFileFactory(new File(directory), true, 1);
       }
       else
       {
-         return new NIOSequentialFileFactory(new File(directory), false);
+         return new NIOSequentialFileFactory(new File(directory), false, 1);
       }
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
index c8f5d8b..22c9628 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
@@ -16,6 +16,10 @@
  */
 package org.apache.activemq.artemis.tests.integration.management;
 
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import java.util.HashMap;
+
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.TransportConfiguration;
 import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
@@ -32,7 +36,6 @@ import org.apache.activemq.artemis.api.core.management.DivertControl;
 import org.apache.activemq.artemis.api.core.management.ObjectNameBuilder;
 import org.apache.activemq.artemis.api.core.management.QueueControl;
 import org.apache.activemq.artemis.api.core.management.RoleInfo;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.messagecounter.impl.MessageCounterManagerImpl;
 import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
@@ -41,6 +44,7 @@ import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.core.server.ActiveMQServers;
 import org.apache.activemq.artemis.core.settings.impl.SlowConsumerPolicy;
 import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.util.RandomUtil;
 import org.apache.activemq.artemis.utils.UUIDGenerator;
 import org.apache.activemq.artemis.utils.json.JSONArray;
@@ -49,10 +53,6 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-import java.util.HashMap;
-
 public class ActiveMQServerControlTest extends ManagementTestBase
 {
 
@@ -118,7 +118,7 @@ public class ActiveMQServerControlTest extends ManagementTestBase
       Assert.assertEquals(conf.isJournalSyncNonTransactional(), serverControl.isJournalSyncNonTransactional());
       Assert.assertEquals(conf.getJournalFileSize(), serverControl.getJournalFileSize());
       Assert.assertEquals(conf.getJournalMinFiles(), serverControl.getJournalMinFiles());
-      if (AsynchronousFileImpl.isLoaded())
+      if (LibaioContext.isLoaded())
       {
          Assert.assertEquals(conf.getJournalMaxIO_AIO(), serverControl.getJournalMaxIO());
          Assert.assertEquals(conf.getJournalBufferSize_AIO(), serverControl.getJournalBufferSize());

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java
index 2990294..d1f4755 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java
@@ -44,18 +44,18 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
 import org.apache.activemq.artemis.api.core.client.ClientSession;
 import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
 import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.core.config.ClusterConnectionConfiguration;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.config.ha.SharedStoreSlavePolicyConfiguration;
 import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
 import org.apache.activemq.artemis.core.journal.IOCompletion;
 import org.apache.activemq.artemis.core.journal.Journal;
 import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
 import org.apache.activemq.artemis.core.journal.LoaderCallback;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
 import org.apache.activemq.artemis.core.journal.impl.JournalFile;
 import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -377,7 +377,7 @@ public final class ReplicationTest extends ActiveMQTestBase
 
       final CountDownLatch latch = new CountDownLatch(1);
 
-      ctx.executeOnCompletion(new IOAsyncTask()
+      ctx.executeOnCompletion(new IOCallback()
       {
          public void onError(final int errorCode, final String errorMessage)
          {
@@ -402,7 +402,7 @@ public final class ReplicationTest extends ActiveMQTestBase
       final CountDownLatch latch2 = new CountDownLatch(1);
 
       // Adding the Task after the exception should still throw an exception
-      ctx.executeOnCompletion(new IOAsyncTask()
+      ctx.executeOnCompletion(new IOCallback()
       {
          public void onError(final int errorCode, final String errorMessage)
          {
@@ -426,7 +426,7 @@ public final class ReplicationTest extends ActiveMQTestBase
 
       final CountDownLatch latch3 = new CountDownLatch(1);
 
-      ctx.executeOnCompletion(new IOAsyncTask()
+      ctx.executeOnCompletion(new IOCallback()
       {
          public void onError(final int errorCode, final String errorMessage)
          {
@@ -488,7 +488,7 @@ public final class ReplicationTest extends ActiveMQTestBase
    private void blockOnReplication(final StorageManager storage, final ReplicationManager manager1) throws Exception
    {
       final CountDownLatch latch = new CountDownLatch(1);
-      storage.afterCompleteOperations(new IOAsyncTask()
+      storage.afterCompleteOperations(new IOCallback()
       {
 
          public void onError(final int errorCode, final String errorMessage)
@@ -518,7 +518,7 @@ public final class ReplicationTest extends ActiveMQTestBase
       replicatedJournal.appendPrepareRecord(1, new FakeData(), false);
 
       final CountDownLatch latch = new CountDownLatch(1);
-      storage.afterCompleteOperations(new IOAsyncTask()
+      storage.afterCompleteOperations(new IOCallback()
       {
 
          public void onError(final int errorCode, final String errorMessage)
@@ -563,7 +563,7 @@ public final class ReplicationTest extends ActiveMQTestBase
             replicatedJournal.appendPrepareRecord(i, new FakeData(), false);
          }
 
-         ctx.executeOnCompletion(new IOAsyncTask()
+         ctx.executeOnCompletion(new IOCallback()
          {
 
             public void onError(final int errorCode, final String errorMessage)

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java
index 6f4b08d..4797e23 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java
@@ -21,9 +21,9 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.config.ha.SharedStoreMasterPolicyConfiguration;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
@@ -53,7 +53,7 @@ public class FileLockTimeoutTest extends ActiveMQTestBase
       {
          Assert.assertTrue(String.format("libAIO is not loaded on %s %s %s", System.getProperty("os.name"),
                                          System.getProperty("os.arch"), System.getProperty("os.version")),
-                           AsynchronousFileImpl.isLoaded()
+                           LibaioContext.isLoaded()
          );
       }
       Configuration config = super.createDefaultInVMConfig()

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java
index 2548b1a..a7f4210 100644
--- a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java
+++ b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.activemq.artemis.tests.performance.journal;
 
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
 
 /**

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java
----------------------------------------------------------------------
diff --git a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java
index 11d6186..17bf397 100644
--- a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java
+++ b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java
@@ -15,22 +15,19 @@
  * limitations under the License.
  */
 package org.apache.activemq.artemis.tests.performance.journal;
-import org.junit.After;
-
-import org.junit.Test;
-
 import java.util.ArrayList;
 
-import org.junit.Assert;
-
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.journal.Journal;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.SimpleEncoding;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
 
 public abstract class JournalImplTestUnit extends JournalImplTestBase
 {
@@ -42,7 +39,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
    {
       super.tearDown();
 
-      Assert.assertEquals(0, AsynchronousFileImpl.getTotalMaxIO());
+      Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
    }
 
    @Test

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java
----------------------------------------------------------------------
diff --git a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java
index 7fa9e14..a73a841 100644
--- a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java
+++ b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java
@@ -17,8 +17,8 @@
 package org.apache.activemq.artemis.tests.performance.journal;
 import java.io.File;
 
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -51,7 +51,7 @@ public class RealJournalImplAIOTest extends JournalImplTestUnit
 
       file.mkdir();
 
-      return new AIOSequentialFileFactory(getTestDirfile());
+      return new AIOSequentialFileFactory(getTestDirfile(), 1);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java
----------------------------------------------------------------------
diff --git a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java
index 4d2fbcf..bc0e7c2 100644
--- a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java
+++ b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java
@@ -18,8 +18,8 @@ package org.apache.activemq.artemis.tests.performance.journal;
 
 import java.io.File;
 
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
 
 public class RealJournalImplNIOTest extends JournalImplTestUnit
@@ -37,7 +37,7 @@ public class RealJournalImplNIOTest extends JournalImplTestUnit
 
       file.mkdir();
 
-      return new NIOSequentialFileFactory(getTestDirfile());
+      return new NIOSequentialFileFactory(getTestDirfile(), 1);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java
index a3a9e1f..eddc347 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java
@@ -18,8 +18,8 @@ package org.apache.activemq.artemis.tests.stress.journal;
 
 import java.io.File;
 
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
 
 public class AIOAllPossibilitiesCompactStressTest extends AllPossibilitiesCompactStressTest
@@ -53,7 +53,7 @@ public class AIOAllPossibilitiesCompactStressTest extends AllPossibilitiesCompac
 
       return new AIOSequentialFileFactory(getTestDirfile(),
                                           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
-                                          1000000,
+                                          1000000, 1000,
                                           false);
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java
index 5b07653..b2a3129 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.activemq.artemis.tests.stress.journal;
 
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.server.JournalType;
 import org.junit.BeforeClass;
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java
index 83ed360..7abc703 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java
@@ -23,8 +23,8 @@ import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.core.journal.LoaderCallback;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
 import org.junit.Assert;
 import org.junit.Test;
@@ -76,7 +76,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
    public void testInsertAndLoad() throws Exception
    {
 
-      SequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile());
+      SequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
       JournalImpl impl = new JournalImpl(10 * 1024 * 1024,
                                          AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
                                          0,
@@ -101,7 +101,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
 
       impl.stop();
 
-      factory = new AIOSequentialFileFactory(getTestDirfile());
+      factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
       impl = new JournalImpl(10 * 1024 * 1024,
                              AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
                              0,
@@ -127,7 +127,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
 
       impl.stop();
 
-      factory = new AIOSequentialFileFactory(getTestDirfile());
+      factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
       impl = new JournalImpl(10 * 1024 * 1024,
                              AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
                              0,
@@ -164,7 +164,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
    public void testInsertUpdateAndLoad() throws Exception
    {
 
-      SequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile());
+      SequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
       JournalImpl impl = new JournalImpl(10 * 1024 * 1024,
                                          AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
                                          0,
@@ -190,7 +190,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
 
       impl.stop();
 
-      factory = new AIOSequentialFileFactory(getTestDirfile());
+      factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
       impl = new JournalImpl(10 * 1024 * 1024, 10, 0, 0, factory, "amq", "amq", 1000);
 
       impl.start();
@@ -209,7 +209,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
 
       impl.stop();
 
-      factory = new AIOSequentialFileFactory(getTestDirfile());
+      factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
       impl = new JournalImpl(10 * 1024 * 1024,
                              AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
                              0,

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java
index 60816b9..49354e4 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java
@@ -16,6 +16,9 @@
  */
 package org.apache.activemq.artemis.tests.stress.journal;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
 import org.apache.activemq.artemis.api.core.Message;
 import org.apache.activemq.artemis.api.core.client.ClientConsumer;
@@ -24,17 +27,14 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
 import org.apache.activemq.artemis.api.core.client.ClientSession;
 import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
 import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.core.server.JournalType;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.junit.Assert;
 import org.junit.Test;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicInteger;
-
 public class CompactingStressTest extends ActiveMQTestBase
 {
 
@@ -69,7 +69,7 @@ public class CompactingStressTest extends ActiveMQTestBase
    @Test
    public void testCleanupAIO() throws Throwable
    {
-      if (AsynchronousFileImpl.isLoaded())
+      if (LibaioContext.isLoaded())
       {
          internalTestCleanup(JournalType.ASYNCIO);
       }
@@ -164,7 +164,7 @@ public class CompactingStressTest extends ActiveMQTestBase
    @Test
    public void testMultiProducerAndCompactAIO() throws Throwable
    {
-      if (AsynchronousFileImpl.isLoaded())
+      if (LibaioContext.isLoaded())
       {
          internalTestMultiProducer(JournalType.ASYNCIO);
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java
index 9516700..3675cd8 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java
@@ -16,26 +16,6 @@
  */
 package org.apache.activemq.artemis.tests.stress.journal;
 
-import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
-import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
-import org.apache.activemq.artemis.tests.util.RandomUtil;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
-import org.apache.activemq.artemis.utils.SimpleIDGenerator;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -52,6 +32,26 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
+import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
+import org.apache.activemq.artemis.core.journal.RecordInfo;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.tests.util.RandomUtil;
+import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
+import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
+import org.apache.activemq.artemis.utils.SimpleIDGenerator;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
 public class JournalCleanupCompactStressTest extends ActiveMQTestBase
 {
 
@@ -112,14 +112,14 @@ public class JournalCleanupCompactStressTest extends ActiveMQTestBase
       SequentialFileFactory factory;
 
       int maxAIO;
-      if (AsynchronousFileImpl.isLoaded())
+      if (LibaioContext.isLoaded())
       {
-         factory = new AIOSequentialFileFactory(dir);
+         factory = new AIOSequentialFileFactory(dir, 10);
          maxAIO = ActiveMQDefaultConfiguration.getDefaultJournalMaxIoAio();
       }
       else
       {
-         factory = new NIOSequentialFileFactory(dir, true);
+         factory = new NIOSequentialFileFactory(dir, true, 1);
          maxAIO = ActiveMQDefaultConfiguration.getDefaultJournalMaxIoNio();
       }
 
@@ -380,7 +380,7 @@ public class JournalCleanupCompactStressTest extends ActiveMQTestBase
                }
                journal.appendCommitRecord(txID, true, ctx);
 
-               ctx.executeOnCompletion(new IOAsyncTask()
+               ctx.executeOnCompletion(new IOCallback()
                {
 
                   public void onError(final int errorCode, final String errorMessage)
@@ -493,7 +493,7 @@ public class JournalCleanupCompactStressTest extends ActiveMQTestBase
       }
    }
 
-   class DeleteTask implements IOAsyncTask
+   class DeleteTask implements IOCallback
    {
       final long[] ids;
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java
index d351fe5..f7edebe 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java
@@ -20,9 +20,9 @@ import java.io.File;
 import java.io.FilenameFilter;
 
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.utils.ReusableLatch;
 import org.apache.activemq.artemis.utils.SimpleIDGenerator;
 import org.junit.After;
@@ -241,6 +241,6 @@ public abstract class MixupCompactorTestBase extends JournalImplTestBase
    @Override
    protected SequentialFileFactory getFileFactory() throws Exception
    {
-      return new NIOSequentialFileFactory(getTestDirfile());
+      return new NIOSequentialFileFactory(getTestDirfile(), 1);
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java
index 616c4a3..4ad8f4e 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java
@@ -32,14 +32,14 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
 import org.apache.activemq.artemis.api.core.client.ClientSession;
 import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
 import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
 import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.core.server.JournalType;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.junit.Assert;
 import org.junit.Before;
@@ -90,7 +90,7 @@ public class NIOMultiThreadCompactorStressTest extends ActiveMQTestBase
          internalTestProduceAndConsume();
          stopServer();
 
-         NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getJournalDir()));
+         NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getJournalDir()), 1);
          JournalImpl journal = new JournalImpl(ActiveMQDefaultConfiguration.getDefaultJournalFileSize(),
                                                2,
                                                0,
@@ -339,7 +339,7 @@ public class NIOMultiThreadCompactorStressTest extends ActiveMQTestBase
 
    private void setupServer(JournalType journalType) throws Exception
    {
-      if (!AsynchronousFileImpl.isLoaded())
+      if (!LibaioContext.isLoaded())
       {
          journalType = JournalType.NIO;
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java
index 385d604..717188a 100644
--- a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java
+++ b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java
@@ -18,8 +18,8 @@ package org.apache.activemq.artemis.tests.timing.core.journal.impl;
 import java.io.File;
 
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
 import org.junit.BeforeClass;
 
 public class AIOJournalImplTest extends JournalImplTestUnit
@@ -39,7 +39,7 @@ public class AIOJournalImplTest extends JournalImplTestUnit
 
       file.mkdir();
 
-      return new AIOSequentialFileFactory(getTestDirfile());
+      return new AIOSequentialFileFactory(getTestDirfile(), 10);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java
index 5702d9d..9e1fb68 100644
--- a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java
+++ b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java
@@ -17,7 +17,7 @@
 package org.apache.activemq.artemis.tests.timing.core.journal.impl;
 
 import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
 
 public class FakeJournalImplTest extends JournalImplTestUnit
 {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java
----------------------------------------------------------------------
diff --git a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java
index 0eab830..3ae3255 100644
--- a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java
+++ b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java
@@ -15,19 +15,16 @@
  * limitations under the License.
  */
 package org.apache.activemq.artemis.tests.timing.core.journal.impl;
-import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
-import org.junit.After;
-
-import org.junit.Test;
-
 import java.util.ArrayList;
 
-import org.junit.Assert;
-
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
 import org.apache.activemq.artemis.core.journal.RecordInfo;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
+import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
 
 public abstract class JournalImplTestUnit extends JournalImplTestBase
 {
@@ -39,7 +36,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
    {
       super.tearDown();
 
-      Assert.assertEquals(0, AsynchronousFileImpl.getTotalMaxIO());
+      Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
    }
 
    @Test

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java
index c607493..842ad3b 100644
--- a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java
+++ b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java
@@ -18,8 +18,8 @@ package org.apache.activemq.artemis.tests.timing.core.journal.impl;
 
 import java.io.File;
 
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
 import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
 
 public class NIOJournalImplTest extends JournalImplTestUnit
@@ -31,7 +31,7 @@ public class NIOJournalImplTest extends JournalImplTestUnit
    {
       File file = new File(getTemporaryDir());
 
-      return new NIOSequentialFileFactory(file);
+      return new NIOSequentialFileFactory(file, 1);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java
index fc17c09..adfccaa 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java
@@ -22,9 +22,10 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -37,25 +38,24 @@ public abstract class AIOTestBase extends ActiveMQTestBase
    // The AIO Test must use a local filesystem. Sometimes $HOME is on a NFS on
    // most enterprise systems
 
-   protected String fileName;
+   protected String fileName = "fileUsedOnNativeTests.log";
 
    @Override
    @Before
    public void setUp() throws Exception
    {
       super.setUp();
-      fileName = getTestDir() + "/fileUsedOnNativeTests.log";
 
       Assert.assertTrue(String.format("libAIO is not loaded on %s %s %s", System.getProperty("os.name"),
                                       System.getProperty("os.arch"), System.getProperty("os.version")),
-                        AsynchronousFileImpl.isLoaded());
+                        LibaioContext.isLoaded());
    }
 
    @Override
    @After
    public void tearDown() throws Exception
    {
-      Assert.assertEquals(0, AsynchronousFileImpl.getTotalMaxIO());
+      Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
 
       super.tearDown();
    }
@@ -73,12 +73,12 @@ public abstract class AIOTestBase extends ActiveMQTestBase
 
    }
 
-   protected void preAlloc(final AsynchronousFileImpl controller, final long size) throws ActiveMQException
+   protected void preAlloc(final LibaioFile controller, final long size) throws ActiveMQException
    {
-      controller.fill(0L, 1, size, (byte)0);
+      controller.fill(size);
    }
 
-   protected static class CountDownCallback implements AIOCallback
+   protected static class CountDownCallback implements IOCallback
    {
       private final CountDownLatch latch;
 


[7/9] activemq-artemis git commit: ARTEMIS-163 First pass on the native AIO refactoring

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFileFactory.java
new file mode 100644
index 0000000..61cd0fd
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFileFactory.java
@@ -0,0 +1,224 @@
+/*
+ * 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.activemq.artemis.core.io;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
+
+/**
+ * An abstract SequentialFileFactory containing basic functionality for both AIO and NIO SequentialFactories
+ */
+public abstract class AbstractSequentialFileFactory implements SequentialFileFactory
+{
+
+   // Timeout used to wait executors to shutdown
+   protected static final int EXECUTOR_TIMEOUT = 60;
+
+   protected final File journalDir;
+
+   protected final TimedBuffer timedBuffer;
+
+   protected final int bufferSize;
+
+   protected final long bufferTimeout;
+
+   protected final int maxIO;
+
+   private final IOCriticalErrorListener critialErrorListener;
+
+   /**
+    * Asynchronous writes need to be done at another executor.
+    * This needs to be done at NIO, or else we would have the callers thread blocking for the return.
+    * At AIO this is necessary as context switches on writes would fire flushes at the kernel.
+    *  */
+   protected ExecutorService writeExecutor;
+
+   protected AbstractSequentialFileFactory(final File journalDir,
+                                        final boolean buffered,
+                                        final int bufferSize,
+                                        final int bufferTimeout,
+                                        final int maxIO,
+                                        final boolean logRates,
+                                        final IOCriticalErrorListener criticalErrorListener)
+   {
+      this.journalDir = journalDir;
+
+      if (buffered && bufferTimeout > 0)
+      {
+         timedBuffer = new TimedBuffer(bufferSize, bufferTimeout, logRates);
+      }
+      else
+      {
+         timedBuffer = null;
+      }
+      this.bufferSize = bufferSize;
+      this.bufferTimeout = bufferTimeout;
+      this.critialErrorListener = criticalErrorListener;
+      this.maxIO = maxIO;
+   }
+
+   public void stop()
+   {
+      if (timedBuffer != null)
+      {
+         timedBuffer.stop();
+      }
+
+      if (isSupportsCallbacks() && writeExecutor != null)
+      {
+         writeExecutor.shutdown();
+
+         try
+         {
+            if (!writeExecutor.awaitTermination(AbstractSequentialFileFactory.EXECUTOR_TIMEOUT, TimeUnit.SECONDS))
+            {
+               ActiveMQJournalLogger.LOGGER.timeoutOnWriterShutdown(new Exception("trace"));
+            }
+         }
+         catch (InterruptedException e)
+         {
+            throw new ActiveMQInterruptedException(e);
+         }
+      }
+   }
+
+   @Override
+   public File getDirectory()
+   {
+      return journalDir;
+   }
+
+   public void start()
+   {
+      if (timedBuffer != null)
+      {
+         timedBuffer.start();
+      }
+
+      if (isSupportsCallbacks())
+      {
+         writeExecutor = Executors.newSingleThreadExecutor(new ActiveMQThreadFactory("ActiveMQ-Asynchronous-Persistent-Writes" + System.identityHashCode(this),
+                                                                                    true,
+                                                                                    AbstractSequentialFileFactory.getThisClassLoader()));
+      }
+   }
+
+   public int getMaxIO()
+   {
+      return maxIO;
+   }
+
+   @Override
+   public void onIOError(Exception exception, String message, SequentialFile file)
+   {
+      if (critialErrorListener != null)
+      {
+         critialErrorListener.onIOException(exception, message, file);
+      }
+   }
+
+   @Override
+   public void activateBuffer(final SequentialFile file)
+   {
+      if (timedBuffer != null)
+      {
+         file.setTimedBuffer(timedBuffer);
+      }
+   }
+
+   public void flush()
+   {
+      if (timedBuffer != null)
+      {
+         timedBuffer.flush();
+      }
+   }
+
+   public void deactivateBuffer()
+   {
+      if (timedBuffer != null)
+      {
+         // When moving to a new file, we need to make sure any pending buffer will be transferred to the buffer
+         timedBuffer.flush();
+         timedBuffer.setObserver(null);
+      }
+   }
+
+   public void releaseBuffer(final ByteBuffer buffer)
+   {
+   }
+
+   /**
+    * Create the directory if it doesn't exist yet
+    */
+   public void createDirs() throws Exception
+   {
+      boolean ok = journalDir.mkdirs();
+      if (!ok)
+      {
+         throw new IOException("Failed to create directory " + journalDir);
+      }
+   }
+
+   public List<String> listFiles(final String extension) throws Exception
+   {
+      FilenameFilter fnf = new FilenameFilter()
+      {
+         public boolean accept(final File file, final String name)
+         {
+            return name.endsWith("." + extension);
+         }
+      };
+
+      String[] fileNames = journalDir.list(fnf);
+
+      if (fileNames == null)
+      {
+         return Collections.EMPTY_LIST;
+      }
+
+      return Arrays.asList(fileNames);
+   }
+
+   private static ClassLoader getThisClassLoader()
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+      {
+         public ClassLoader run()
+         {
+            return AbstractSequentialFileFactory.class.getClassLoader();
+         }
+      });
+
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/DummyCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/DummyCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/DummyCallback.java
new file mode 100644
index 0000000..ce21f2a
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/DummyCallback.java
@@ -0,0 +1,49 @@
+/*
+ * 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.activemq.artemis.core.io;
+
+import org.apache.activemq.artemis.core.journal.impl.SyncIOCompletion;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+
+public class DummyCallback extends SyncIOCompletion
+{
+   private static final DummyCallback instance = new DummyCallback();
+
+   public static DummyCallback getInstance()
+   {
+      return DummyCallback.instance;
+   }
+
+   public void done()
+   {
+   }
+
+   public void onError(final int errorCode, final String errorMessage)
+   {
+      ActiveMQJournalLogger.LOGGER.errorWritingData(new Exception(errorMessage), errorMessage, errorCode);
+   }
+
+   @Override
+   public void waitCompletion() throws Exception
+   {
+   }
+
+   @Override
+   public void storeLineUp()
+   {
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCallback.java
new file mode 100644
index 0000000..41470e4
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCallback.java
@@ -0,0 +1,33 @@
+/*
+ * 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.activemq.artemis.core.io;
+
+/**
+ * The interface used for AIO Callbacks.
+ */
+public interface IOCallback
+{
+   /**
+    * Method for sync notifications. When this callback method is called, there is a guarantee the data is written on the disk.
+    * <br><b>Note:</b><i>Leave this method as soon as possible, or you would be blocking the whole notification thread</i> */
+   void done();
+
+   /**
+    * Method for error notifications.
+    * Observation: The whole file will be probably failing if this happens. Like, if you delete the file, you will start to get errors for these operations*/
+   void onError(int errorCode, String errorMessage);
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCriticalErrorListener.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCriticalErrorListener.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCriticalErrorListener.java
new file mode 100644
index 0000000..f2da3e8
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCriticalErrorListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.activemq.artemis.core.io;
+
+/**
+ * TODO Merge this with IOExceptionListener
+ */
+public interface IOCriticalErrorListener
+{
+   void onIOException(Exception code, String message, SequentialFile file);
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOExceptionListener.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOExceptionListener.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOExceptionListener.java
new file mode 100644
index 0000000..5c855e5
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOExceptionListener.java
@@ -0,0 +1,22 @@
+/*
+ * 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.activemq.artemis.core.io;
+
+public interface IOExceptionListener
+{
+   void onIOException(Exception exception, String message);
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFile.java
new file mode 100644
index 0000000..cb9d070
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFile.java
@@ -0,0 +1,116 @@
+/*
+ * 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.activemq.artemis.core.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.core.journal.EncodingSupport;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
+
+public interface SequentialFile
+{
+
+   boolean isOpen();
+
+   boolean exists();
+
+   void open() throws Exception;
+
+   /**
+    * The maximum number of simultaneous writes accepted
+    * @param maxIO
+    * @throws Exception
+    */
+   void open(int maxIO, boolean useExecutor) throws Exception;
+
+   boolean fits(int size);
+
+   int getAlignment() throws Exception;
+
+   int calculateBlockStart(int position) throws Exception;
+
+   String getFileName();
+
+   void fill(int size) throws Exception;
+
+   void delete() throws IOException, InterruptedException, ActiveMQException;
+
+   void write(ActiveMQBuffer bytes, boolean sync, IOCallback callback) throws Exception;
+
+   void write(ActiveMQBuffer bytes, boolean sync) throws Exception;
+
+   void write(EncodingSupport bytes, boolean sync, IOCallback callback) throws Exception;
+
+   void write(EncodingSupport bytes, boolean sync) throws Exception;
+
+   /**
+    * Write directly to the file without using any buffer
+    * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
+    *           NIO). To be safe, use a buffer from the corresponding
+    *           {@link SequentialFileFactory#newBuffer(int)}.
+    */
+   void writeDirect(ByteBuffer bytes, boolean sync, IOCallback callback);
+
+   /**
+    * Write directly to the file without using intermediate any buffer
+    * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
+    *           NIO). To be safe, use a buffer from the corresponding
+    *           {@link SequentialFileFactory#newBuffer(int)}.
+    */
+   void writeDirect(ByteBuffer bytes, boolean sync) throws Exception;
+
+   /**
+    * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
+    *           NIO). To be safe, use a buffer from the corresponding
+    *           {@link SequentialFileFactory#newBuffer(int)}.
+    */
+   int read(ByteBuffer bytes, IOCallback callback) throws Exception;
+
+   /**
+    * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
+    *           NIO). To be safe, use a buffer from the corresponding
+    *           {@link SequentialFileFactory#newBuffer(int)}.
+    */
+   int read(ByteBuffer bytes) throws Exception;
+
+   void position(long pos) throws IOException;
+
+   long position();
+
+   void close() throws Exception;
+
+   void sync() throws IOException;
+
+   long size() throws Exception;
+
+   void renameTo(String newFileName) throws Exception;
+
+   SequentialFile cloneFile();
+
+   void copyTo(SequentialFile newFileName) throws Exception;
+
+   void setTimedBuffer(TimedBuffer buffer);
+
+   /**
+    * Returns a native File of the file underlying this sequential file.
+    */
+   File getJavaFile();
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFileFactory.java
new file mode 100644
index 0000000..b9a72ca
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFileFactory.java
@@ -0,0 +1,91 @@
+/*
+ * 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.activemq.artemis.core.io;
+
+import java.io.File;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ *
+ * A SequentialFileFactory
+ */
+public interface SequentialFileFactory
+{
+   SequentialFile createSequentialFile(String fileName);
+
+   int getMaxIO();
+
+   /**
+    * Lists files that end with the given extension.
+    * <p>
+    * This method inserts a ".' before the extension.
+    * @param extension
+    * @return
+    * @throws Exception
+    */
+   List<String> listFiles(String extension) throws Exception;
+
+   boolean isSupportsCallbacks();
+
+   /** The SequentialFile will call this method when a disk IO Error happens during the live phase. */
+   void onIOError(Exception exception, String message, SequentialFile file);
+
+   /** used for cases where you need direct buffer outside of the journal context.
+    *  This is because the native layer has a method that can be reused in certain cases like paging */
+   ByteBuffer allocateDirectBuffer(int size);
+
+   /** used for cases where you need direct buffer outside of the journal context.
+    *  This is because the native layer has a method that can be reused in certain cases like paging */
+   void releaseDirectBuffer(ByteBuffer buffer);
+
+   /**
+    * Note: You need to release the buffer if is used for reading operations. You don't need to do
+    * it if using writing operations (AIO Buffer Lister will take of writing operations)
+    * @param size
+    * @return the allocated ByteBuffer
+    */
+   ByteBuffer newBuffer(int size);
+
+   void releaseBuffer(ByteBuffer buffer);
+
+   void activateBuffer(SequentialFile file);
+
+   void deactivateBuffer();
+
+   // To be used in tests only
+   ByteBuffer wrapBuffer(byte[] bytes);
+
+   int getAlignment();
+
+   int calculateBlockSize(int bytes);
+
+   File getDirectory();
+
+   void clearBuffer(ByteBuffer buffer);
+
+   void start();
+
+   void stop();
+
+   /**
+    * Creates the directory if it does not exist yet.
+    */
+   void createDirs() throws Exception;
+
+   void flush();
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFile.java
new file mode 100644
index 0000000..7503681
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFile.java
@@ -0,0 +1,333 @@
+/*
+ * 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.activemq.artemis.core.io.aio;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.PriorityQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQNativeIOError;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.AbstractSequentialFile;
+import org.apache.activemq.artemis.core.io.DummyCallback;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.journal.impl.SimpleWaitIOCallback;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
+import org.apache.activemq.artemis.utils.ReusableLatch;
+
+public class AIOSequentialFile extends AbstractSequentialFile
+{
+   private boolean opened = false;
+
+   private LibaioFile aioFile;
+
+   private final AIOSequentialFileFactory aioFactory;
+
+   private final ReusableLatch pendingCallbacks = new ReusableLatch();
+
+   /**
+    * Used to determine the next writing sequence
+    */
+   private final AtomicLong nextWritingSequence = new AtomicLong(0);
+
+   /**
+    * AIO can't guarantee ordering over callbacks.
+    * <br>
+    * We use this {@link PriorityQueue} to hold values until they are in order
+    */
+   final PriorityQueue<AIOSequentialFileFactory.AIOSequentialCallback> pendingCallbackList = new PriorityQueue<>();
+
+   /**
+    * Used to determine the next writing sequence.
+    * This is accessed from a single thread (the Poller Thread)
+    */
+   private long nextReadSequence = 0;
+
+
+   public AIOSequentialFile(final AIOSequentialFileFactory factory,
+                            final int bufferSize,
+                            final long bufferTimeoutMilliseconds,
+                            final File directory,
+                            final String fileName,
+                            final Executor writerExecutor)
+   {
+      super(directory, fileName, factory, writerExecutor);
+      this.aioFactory = factory;
+   }
+
+   public boolean isOpen()
+   {
+      return opened;
+   }
+
+   public int getAlignment()
+   {
+      checkOpened();
+
+      return aioFile.getBlockSize();
+   }
+
+   public int calculateBlockStart(final int position)
+   {
+      int alignment = getAlignment();
+
+      int pos = (position / alignment + (position % alignment != 0 ? 1 : 0)) * alignment;
+
+      return pos;
+   }
+
+   public SequentialFile cloneFile()
+   {
+      return new AIOSequentialFile(aioFactory,
+                                   -1,
+                                   -1,
+                                   getFile().getParentFile(),
+                                   getFile().getName(),
+                                   writerExecutor);
+   }
+
+   @Override
+   public synchronized void close() throws IOException, InterruptedException, ActiveMQException
+   {
+      if (!opened)
+      {
+         return;
+      }
+
+      super.close();
+
+      if (!pendingCallbacks.await(10, TimeUnit.SECONDS))
+      {
+         factory.onIOError(new IOException("Timeout on close"), "Timeout on close", this);
+      }
+
+      opened = false;
+
+      timedBuffer = null;
+
+      aioFile.close();
+      aioFile = null;
+   }
+
+
+   public synchronized void fill(final int size) throws Exception
+   {
+      checkOpened();
+      aioFile.fill(size);
+
+      fileSize = aioFile.getSize();
+   }
+
+   public void open() throws Exception
+   {
+      open(aioFactory.getMaxIO(), true);
+   }
+
+   public synchronized void open(final int maxIO, final boolean useExecutor) throws ActiveMQException
+   {
+      opened = true;
+
+      try
+      {
+         aioFile = aioFactory.libaioContext.openFile(getFile(), true);
+      }
+      catch (IOException e)
+      {
+         factory.onIOError(e, e.getMessage(), this);
+         throw new ActiveMQNativeIOError(e.getMessage(), e);
+      }
+
+      position.set(0);
+
+      fileSize = aioFile.getSize();
+   }
+
+   public int read(final ByteBuffer bytes, final IOCallback callback) throws ActiveMQException
+   {
+      checkOpened();
+      int bytesToRead = bytes.limit();
+
+      long positionToRead = position.getAndAdd(bytesToRead);
+
+      bytes.rewind();
+
+      try
+      {
+         // We don't send the buffer to the callback on read,
+         // because we want the buffer available.
+         // Sending it through the callback would make it released
+         aioFile.read(positionToRead, bytesToRead, bytes, getCallback(callback, null));
+      }
+      catch (IOException e)
+      {
+         factory.onIOError(e, e.getMessage(), this);
+         throw new ActiveMQNativeIOError(e.getMessage(), e);
+      }
+
+      return bytesToRead;
+   }
+
+   public int read(final ByteBuffer bytes) throws Exception
+   {
+      SimpleWaitIOCallback waitCompletion = new SimpleWaitIOCallback();
+
+      int bytesRead = read(bytes, waitCompletion);
+
+      waitCompletion.waitCompletion();
+
+      return bytesRead;
+   }
+
+   public void writeDirect(final ByteBuffer bytes, final boolean sync) throws Exception
+   {
+      if (sync)
+      {
+         SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
+
+         writeDirect(bytes, true, completion);
+
+         completion.waitCompletion();
+      }
+      else
+      {
+         writeDirect(bytes, false, DummyCallback.getInstance());
+      }
+   }
+
+   /**
+    *
+    * Note: Parameter sync is not used on AIO
+    *  */
+   public void writeDirect(final ByteBuffer bytes, final boolean sync, final IOCallback callback)
+   {
+      checkOpened();
+
+      final int bytesToWrite = factory.calculateBlockSize(bytes.limit());
+
+      final long positionToWrite = position.getAndAdd(bytesToWrite);
+
+      AIOSequentialFileFactory.AIOSequentialCallback runnableCallback = getCallback(callback, bytes);
+      runnableCallback.initWrite(positionToWrite, bytesToWrite);
+      if (writerExecutor != null)
+      {
+         writerExecutor.execute(runnableCallback);
+      }
+      else
+      {
+         runnableCallback.run();
+      }
+   }
+
+
+
+   AIOSequentialFileFactory.AIOSequentialCallback getCallback(IOCallback originalCallback, ByteBuffer buffer)
+   {
+      AIOSequentialFileFactory.AIOSequentialCallback callback = aioFactory.getCallback();
+      callback.init(this.nextWritingSequence.getAndIncrement(), originalCallback, aioFile, this, buffer);
+      pendingCallbacks.countUp();
+      return callback;
+   }
+
+
+   void done(AIOSequentialFileFactory.AIOSequentialCallback callback)
+   {
+      if (callback.writeSequence == -1)
+      {
+         callback.sequentialDone();
+         pendingCallbacks.countDown();
+      }
+
+
+      if (callback.writeSequence == nextReadSequence)
+      {
+         nextReadSequence++;
+         callback.sequentialDone();
+         pendingCallbacks.countDown();
+         flushCallbacks();
+      }
+      else
+      {
+         pendingCallbackList.add(callback);
+      }
+
+   }
+
+   private void flushCallbacks()
+   {
+      while (!pendingCallbackList.isEmpty() && pendingCallbackList.peek().writeSequence == nextReadSequence)
+      {
+         AIOSequentialFileFactory.AIOSequentialCallback callback = pendingCallbackList.poll();
+         callback.sequentialDone();
+         nextReadSequence++;
+         pendingCallbacks.countDown();
+      }
+   }
+
+   public void sync()
+   {
+      throw new UnsupportedOperationException("This method is not supported on AIO");
+   }
+
+   public long size() throws Exception
+   {
+      if (aioFile == null)
+      {
+         return getFile().length();
+      }
+      else
+      {
+         return aioFile.getSize();
+      }
+   }
+
+   @Override
+   public String toString()
+   {
+      return "AIOSequentialFile:" + getFile().getAbsolutePath();
+   }
+
+   // Protected methods
+   // -----------------------------------------------------------------------------------------------------
+
+   @Override
+   protected ByteBuffer newBuffer(int size, int limit)
+   {
+      size = factory.calculateBlockSize(size);
+      limit = factory.calculateBlockSize(limit);
+
+      ByteBuffer buffer = factory.newBuffer(size);
+      buffer.limit(limit);
+      return buffer;
+   }
+
+   // Private methods
+   // -----------------------------------------------------------------------------------------------------
+
+   private void checkOpened()
+   {
+      if (aioFile == null || !opened)
+      {
+         throw new NullPointerException("File not opened, file=null");
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java
new file mode 100644
index 0000000..39dad2f
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java
@@ -0,0 +1,531 @@
+/*
+ * 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.activemq.artemis.core.io.aio;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
+import org.apache.activemq.artemis.core.io.AbstractSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
+import org.apache.activemq.artemis.jlibaio.SubmitInfo;
+import org.apache.activemq.artemis.jlibaio.util.CallbackCache;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
+
+public final class AIOSequentialFileFactory extends AbstractSequentialFileFactory
+{
+   private static final boolean trace = ActiveMQJournalLogger.LOGGER.isTraceEnabled();
+
+   private final ReuseBuffersController buffersControl = new ReuseBuffersController();
+
+   private volatile boolean reuseBuffers = true;
+
+   private ExecutorService pollerExecutor;
+
+   volatile LibaioContext<AIOSequentialCallback> libaioContext;
+
+   private final CallbackCache<AIOSequentialCallback> callbackPool;
+
+   private final AtomicBoolean running = new AtomicBoolean(false);
+
+   // This method exists just to make debug easier.
+   // I could replace log.trace by log.info temporarily while I was debugging
+   // Journal
+   private static void trace(final String message)
+   {
+      ActiveMQJournalLogger.LOGGER.trace(message);
+   }
+
+   public AIOSequentialFileFactory(final File journalDir, int maxIO)
+   {
+      this(journalDir,
+           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
+           JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
+           maxIO,
+           false,
+           null);
+   }
+
+   public AIOSequentialFileFactory(final File journalDir, final IOCriticalErrorListener listener, int maxIO)
+   {
+      this(journalDir,
+           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
+           JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
+           maxIO,
+           false,
+           listener);
+   }
+
+   public AIOSequentialFileFactory(final File journalDir,
+                                   final int bufferSize,
+                                   final int bufferTimeout,
+                                   final int maxIO,
+                                   final boolean logRates)
+   {
+      this(journalDir, bufferSize, bufferTimeout, maxIO, logRates, null);
+   }
+
+   public AIOSequentialFileFactory(final File journalDir,
+                                   final int bufferSize,
+                                   final int bufferTimeout,
+                                   final int maxIO,
+                                   final boolean logRates,
+                                   final IOCriticalErrorListener listener)
+   {
+      super(journalDir, true, bufferSize, bufferTimeout, maxIO, logRates, listener);
+      callbackPool = new CallbackCache<>(maxIO);
+   }
+
+   public AIOSequentialCallback getCallback()
+   {
+      AIOSequentialCallback callback = callbackPool.get();
+      if (callback == null)
+      {
+         callback = new AIOSequentialCallback();
+      }
+
+      return callback;
+   }
+
+   public void enableBufferReuse()
+   {
+      this.reuseBuffers = true;
+   }
+
+   public void disableBufferReuse()
+   {
+      this.reuseBuffers = false;
+   }
+
+
+   public SequentialFile createSequentialFile(final String fileName)
+   {
+      return new AIOSequentialFile(this,
+                                   bufferSize,
+                                   bufferTimeout,
+                                   journalDir,
+                                   fileName,
+                                   writeExecutor);
+   }
+
+   public boolean isSupportsCallbacks()
+   {
+      return true;
+   }
+
+   public static boolean isSupported()
+   {
+      return LibaioContext.isLoaded();
+   }
+
+   public ByteBuffer allocateDirectBuffer(final int size)
+   {
+
+      int blocks = size / 512;
+      if (size % 512 != 0)
+      {
+         blocks++;
+      }
+
+      // The buffer on AIO has to be a multiple of 512
+      ByteBuffer buffer = LibaioContext.newAlignedBuffer(blocks * 512, 512);
+
+      buffer.limit(size);
+
+      return buffer;
+   }
+
+   public void releaseDirectBuffer(final ByteBuffer buffer)
+   {
+      LibaioContext.freeBuffer(buffer);
+   }
+
+   public ByteBuffer newBuffer(int size)
+   {
+      if (size % 512 != 0)
+      {
+         size = (size / 512 + 1) * 512;
+      }
+
+      return buffersControl.newBuffer(size);
+   }
+
+   public void clearBuffer(final ByteBuffer directByteBuffer)
+   {
+      directByteBuffer.position(0);
+      libaioContext.memsetBuffer(directByteBuffer);
+   }
+
+   public int getAlignment()
+   {
+      return 512;
+   }
+
+   // For tests only
+   public ByteBuffer wrapBuffer(final byte[] bytes)
+   {
+      ByteBuffer newbuffer = newBuffer(bytes.length);
+      newbuffer.put(bytes);
+      return newbuffer;
+   }
+
+   public int calculateBlockSize(final int position)
+   {
+      int alignment = getAlignment();
+
+      int pos = (position / alignment + (position % alignment != 0 ? 1 : 0)) * alignment;
+
+      return pos;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.activemq.artemis.core.io.SequentialFileFactory#releaseBuffer(java.nio.ByteBuffer)
+    */
+   @Override
+   public synchronized void releaseBuffer(final ByteBuffer buffer)
+   {
+      LibaioContext.freeBuffer(buffer);
+   }
+
+   @Override
+   public void start()
+   {
+      if (running.compareAndSet(false, true))
+      {
+         super.start();
+
+         this.libaioContext = new LibaioContext(maxIO, true);
+
+         this.running.set(true);
+
+         pollerExecutor = Executors.newCachedThreadPool(new ActiveMQThreadFactory("ActiveMQ-AIO-poller-pool" + System.identityHashCode(this),
+                                                                                  true,
+                                                                                  AIOSequentialFileFactory.getThisClassLoader()));
+
+         pollerExecutor.execute(new PollerRunnable());
+      }
+
+   }
+
+   @Override
+   public void stop()
+   {
+      if (this.running.compareAndSet(true, false))
+      {
+         buffersControl.stop();
+
+         libaioContext.close();
+         libaioContext = null;
+
+         if (pollerExecutor != null)
+         {
+            pollerExecutor.shutdown();
+
+            try
+            {
+               if (!pollerExecutor.awaitTermination(AbstractSequentialFileFactory.EXECUTOR_TIMEOUT, TimeUnit.SECONDS))
+               {
+                  ActiveMQJournalLogger.LOGGER.timeoutOnPollerShutdown(new Exception("trace"));
+               }
+            }
+            catch (InterruptedException e)
+            {
+               throw new ActiveMQInterruptedException(e);
+            }
+         }
+
+         super.stop();
+      }
+   }
+
+   @Override
+   protected void finalize()
+   {
+      stop();
+   }
+
+   /**
+    * The same callback is used for Runnable executor.
+    * This way we can save some memory over the pool.
+    */
+   public class AIOSequentialCallback implements SubmitInfo, Runnable, Comparable<AIOSequentialCallback>
+   {
+      IOCallback callback;
+      boolean error = false;
+      AIOSequentialFile sequentialFile;
+      ByteBuffer buffer;
+      LibaioFile libaioFile;
+      String errorMessage;
+      int errorCode = -1;
+      long writeSequence;
+
+      long position;
+      int bytes;
+
+      @Override
+      public String toString()
+      {
+         return "AIOSequentialCallback{" +
+            "error=" + error +
+            ", errorMessage='" + errorMessage + '\'' +
+            ", errorCode=" + errorCode +
+            ", writeSequence=" + writeSequence +
+            ", position=" + position +
+            '}';
+      }
+
+      public AIOSequentialCallback initWrite(long positionToWrite, int bytesToWrite)
+      {
+         this.position = positionToWrite;
+         this.bytes = bytesToWrite;
+         return this;
+      }
+
+      public void run()
+      {
+         try
+         {
+            libaioFile.write(position, bytes, buffer, this);
+         }
+         catch (IOException e)
+         {
+            callback.onError(-1, e.getMessage());
+         }
+      }
+
+      public int compareTo(AIOSequentialCallback other)
+      {
+         if (this == other || this.writeSequence == other.writeSequence)
+         {
+            return 0;
+         }
+         else if (other.writeSequence < this.writeSequence)
+         {
+            return 1;
+         }
+         else
+         {
+            return -1;
+         }
+      }
+
+      public AIOSequentialCallback init(long writeSequence, IOCallback IOCallback, LibaioFile libaioFile, AIOSequentialFile sequentialFile, ByteBuffer usedBuffer)
+      {
+         this.callback = IOCallback;
+         this.sequentialFile = sequentialFile;
+         this.error = false;
+         this.buffer = usedBuffer;
+         this.libaioFile = libaioFile;
+         this.writeSequence = writeSequence;
+         this.errorMessage = null;
+         return this;
+      }
+
+      @Override
+      public void onError(int errno, String message)
+      {
+         this.error = true;
+         this.errorCode = errno;
+         this.errorMessage = message;
+      }
+
+      /**
+       * this is called by libaio.
+       */
+      public void done()
+      {
+         this.sequentialFile.done(this);
+      }
+
+      /**
+       * This is callbed by the AIOSequentialFile, after determined the callbacks were returned in sequence
+       */
+      public void sequentialDone()
+      {
+
+         if (error)
+         {
+            callback.onError(errorCode, errorMessage);
+            errorMessage = null;
+         }
+         else
+         {
+            if (callback != null)
+            {
+               callback.done();
+            }
+
+            if (buffer != null && reuseBuffers)
+            {
+               buffersControl.bufferDone(buffer);
+            }
+
+            callbackPool.put(AIOSequentialCallback.this);
+         }
+      }
+   }
+
+   private class PollerRunnable implements Runnable
+   {
+      public void run()
+      {
+         libaioContext.poll();
+      }
+   }
+
+   /**
+    * Class that will control buffer-reuse
+    */
+   private class ReuseBuffersController
+   {
+      private volatile long bufferReuseLastTime = System.currentTimeMillis();
+
+      private final ConcurrentLinkedQueue<ByteBuffer> reuseBuffersQueue = new ConcurrentLinkedQueue<ByteBuffer>();
+
+      private boolean stopped = false;
+
+      public ByteBuffer newBuffer(final int size)
+      {
+         // if a new buffer wasn't requested in 10 seconds, we clear the queue
+         // This is being done this way as we don't need another Timeout Thread
+         // just to cleanup this
+         if (bufferSize > 0 && System.currentTimeMillis() - bufferReuseLastTime > 10000)
+         {
+            if (AIOSequentialFileFactory.trace)
+            {
+               AIOSequentialFileFactory.trace("Clearing reuse buffers queue with " + reuseBuffersQueue.size() +
+                                                 " elements");
+            }
+
+            bufferReuseLastTime = System.currentTimeMillis();
+
+            clearPoll();
+         }
+
+         // if a buffer is bigger than the configured-bufferSize, we just create a new
+         // buffer.
+         if (size > bufferSize)
+         {
+            return LibaioContext.newAlignedBuffer(size, 512);
+         }
+         else
+         {
+            // We need to allocate buffers following the rules of the storage
+            // being used (AIO/NIO)
+            int alignedSize = calculateBlockSize(size);
+
+            // Try getting a buffer from the queue...
+            ByteBuffer buffer = reuseBuffersQueue.poll();
+
+            if (buffer == null)
+            {
+               // if empty create a new one.
+               buffer = LibaioContext.newAlignedBuffer(size, 512);
+
+               buffer.limit(alignedSize);
+            }
+            else
+            {
+               clearBuffer(buffer);
+
+               // set the limit of the buffer to the bufferSize being required
+               buffer.limit(alignedSize);
+            }
+
+            buffer.rewind();
+
+            return buffer;
+         }
+      }
+
+      public synchronized void stop()
+      {
+         stopped = true;
+         clearPoll();
+      }
+
+      public synchronized void clearPoll()
+      {
+         ByteBuffer reusedBuffer;
+
+         while ((reusedBuffer = reuseBuffersQueue.poll()) != null)
+         {
+            releaseBuffer(reusedBuffer);
+         }
+      }
+
+      public void bufferDone(final ByteBuffer buffer)
+      {
+         synchronized (this)
+         {
+
+            if (stopped)
+            {
+               releaseBuffer(buffer);
+            }
+            else
+            {
+               bufferReuseLastTime = System.currentTimeMillis();
+
+               // If a buffer has any other than the configured bufferSize, the buffer
+               // will be just sent to GC
+               if (buffer.capacity() == bufferSize)
+               {
+                  reuseBuffersQueue.offer(buffer);
+               }
+               else
+               {
+                  releaseBuffer(buffer);
+               }
+            }
+         }
+      }
+   }
+
+   private static ClassLoader getThisClassLoader()
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+      {
+         public ClassLoader run()
+         {
+            return AIOSequentialFileFactory.class.getClassLoader();
+         }
+      });
+
+   }
+
+   @Override
+   public String toString()
+   {
+      return AIOSequentialFileFactory.class.getSimpleName() + "(buffersControl.stopped=" + buffersControl.stopped +
+         "):" + super.toString();
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/ActiveMQFileLock.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/ActiveMQFileLock.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/ActiveMQFileLock.java
new file mode 100644
index 0000000..a184244
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/ActiveMQFileLock.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.activemq.artemis.core.io.aio;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
+
+public class ActiveMQFileLock extends FileLock
+{
+
+   private final LibaioFile file;
+
+   public ActiveMQFileLock(final LibaioFile handle)
+   {
+      super((FileChannel)null, 0, 0, false);
+      this.file = handle;
+   }
+
+   @Override
+   public boolean isValid()
+   {
+      return true;
+   }
+
+   @Override
+   public void release() throws IOException
+   {
+      file.close();
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBuffer.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBuffer.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBuffer.java
new file mode 100644
index 0000000..a61569a
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBuffer.java
@@ -0,0 +1,558 @@
+/*
+ * 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.activemq.artemis.core.io.buffer;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
+import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.journal.EncodingSupport;
+import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+
+public class TimedBuffer
+{
+   // Constants -----------------------------------------------------
+
+   // The number of tries on sleep before switching to spin
+   public static final int MAX_CHECKS_ON_SLEEP = 20;
+
+   // Attributes ----------------------------------------------------
+
+   private TimedBufferObserver bufferObserver;
+
+   // If the TimedBuffer is idle - i.e. no records are being added, then it's pointless the timer flush thread
+   // in spinning and checking the time - and using up CPU in the process - this semaphore is used to
+   // prevent that
+   private final Semaphore spinLimiter = new Semaphore(1);
+
+   private CheckTimer timerRunnable = new CheckTimer();
+
+   private final int bufferSize;
+
+   private final ActiveMQBuffer buffer;
+
+   private int bufferLimit = 0;
+
+   private List<IOCallback> callbacks;
+
+   private volatile int timeout;
+
+   // used to measure sync requests. When a sync is requested, it shouldn't take more than timeout to happen
+   private volatile boolean pendingSync = false;
+
+   private Thread timerThread;
+
+   private volatile boolean started;
+
+   // We use this flag to prevent flush occurring between calling checkSize and addBytes
+   // CheckSize must always be followed by it's corresponding addBytes otherwise the buffer
+   // can get in an inconsistent state
+   private boolean delayFlush;
+
+   // for logging write rates
+
+   private final boolean logRates;
+
+   private final AtomicLong bytesFlushed = new AtomicLong(0);
+
+   private final AtomicLong flushesDone = new AtomicLong(0);
+
+   private Timer logRatesTimer;
+
+   private TimerTask logRatesTimerTask;
+
+   private boolean useSleep = true;
+
+   // no need to be volatile as every access is synchronized
+   private boolean spinning = false;
+
+   // Static --------------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   // Public --------------------------------------------------------
+
+   public TimedBuffer(final int size, final int timeout, final boolean logRates)
+   {
+      bufferSize = size;
+
+      this.logRates = logRates;
+
+      if (logRates)
+      {
+         logRatesTimer = new Timer(true);
+      }
+      // Setting the interval for nano-sleeps
+
+      buffer = ActiveMQBuffers.fixedBuffer(bufferSize);
+
+      buffer.clear();
+
+      bufferLimit = 0;
+
+      callbacks = new ArrayList<IOCallback>();
+
+      this.timeout = timeout;
+   }
+
+   // for Debug purposes
+   public synchronized boolean isUseSleep()
+   {
+      return useSleep;
+   }
+
+   public synchronized void setUseSleep(boolean useSleep)
+   {
+      this.useSleep = useSleep;
+   }
+
+   public synchronized void start()
+   {
+      if (started)
+      {
+         return;
+      }
+
+      // Need to start with the spin limiter acquired
+      try
+      {
+         spinLimiter.acquire();
+      }
+      catch (InterruptedException e)
+      {
+         throw new ActiveMQInterruptedException(e);
+      }
+
+      timerRunnable = new CheckTimer();
+
+      timerThread = new Thread(timerRunnable, "activemq-buffer-timeout");
+
+      timerThread.start();
+
+      if (logRates)
+      {
+         logRatesTimerTask = new LogRatesTimerTask();
+
+         logRatesTimer.scheduleAtFixedRate(logRatesTimerTask, 2000, 2000);
+      }
+
+      started = true;
+   }
+
+   public void stop()
+   {
+      if (!started)
+      {
+         return;
+      }
+
+      flush();
+
+      bufferObserver = null;
+
+      timerRunnable.close();
+
+      spinLimiter.release();
+
+      if (logRates)
+      {
+         logRatesTimerTask.cancel();
+      }
+
+      while (timerThread.isAlive())
+      {
+         try
+         {
+            timerThread.join();
+         }
+         catch (InterruptedException e)
+         {
+            throw new ActiveMQInterruptedException(e);
+         }
+      }
+
+      started = false;
+   }
+
+   public synchronized void setObserver(final TimedBufferObserver observer)
+   {
+      if (bufferObserver != null)
+      {
+         flush();
+      }
+
+      bufferObserver = observer;
+   }
+
+   /**
+    * Verify if the size fits the buffer
+    *
+    * @param sizeChecked
+    */
+   public synchronized boolean checkSize(final int sizeChecked)
+   {
+      if (!started)
+      {
+         throw new IllegalStateException("TimedBuffer is not started");
+      }
+
+      if (sizeChecked > bufferSize)
+      {
+         throw new IllegalStateException("Can't write records bigger than the bufferSize(" + bufferSize +
+                                            ") on the journal");
+      }
+
+      if (bufferLimit == 0 || buffer.writerIndex() + sizeChecked > bufferLimit)
+      {
+         // Either there is not enough space left in the buffer for the sized record
+         // Or a flush has just been performed and we need to re-calcualate bufferLimit
+
+         flush();
+
+         delayFlush = true;
+
+         final int remainingInFile = bufferObserver.getRemainingBytes();
+
+         if (sizeChecked > remainingInFile)
+         {
+            return false;
+         }
+         else
+         {
+            // There is enough space in the file for this size
+
+            // Need to re-calculate buffer limit
+
+            bufferLimit = Math.min(remainingInFile, bufferSize);
+
+            return true;
+         }
+      }
+      else
+      {
+         delayFlush = true;
+
+         return true;
+      }
+   }
+
+   public synchronized void addBytes(final ActiveMQBuffer bytes, final boolean sync, final IOCallback callback)
+   {
+      addBytes(new ByteArrayEncoding(bytes.toByteBuffer().array()), sync, callback);
+   }
+
+   public synchronized void addBytes(final EncodingSupport bytes, final boolean sync, final IOCallback callback)
+   {
+      if (!started)
+      {
+         throw new IllegalStateException("TimedBuffer is not started");
+      }
+
+      delayFlush = false;
+
+      bytes.encode(buffer);
+
+      callbacks.add(callback);
+
+      if (sync)
+      {
+         pendingSync = true;
+
+         startSpin();
+      }
+
+   }
+
+   public void flush()
+   {
+      flush(false);
+   }
+
+   /**
+    * force means the Journal is moving to a new file. Any pending write need to be done immediately
+    * or data could be lost
+    */
+   public void flush(final boolean force)
+   {
+      synchronized (this)
+      {
+         if (!started)
+         {
+            throw new IllegalStateException("TimedBuffer is not started");
+         }
+
+         if ((force || !delayFlush) && buffer.writerIndex() > 0)
+         {
+            int pos = buffer.writerIndex();
+
+            if (logRates)
+            {
+               bytesFlushed.addAndGet(pos);
+            }
+
+            ByteBuffer bufferToFlush = bufferObserver.newBuffer(bufferSize, pos);
+
+            // Putting a byteArray on a native buffer is much faster, since it will do in a single native call.
+            // Using bufferToFlush.put(buffer) would make several append calls for each byte
+            // We also transfer the content of this buffer to the native file's buffer
+
+            bufferToFlush.put(buffer.toByteBuffer().array(), 0, pos);
+
+            bufferObserver.flushBuffer(bufferToFlush, pendingSync, callbacks);
+
+            stopSpin();
+
+            pendingSync = false;
+
+            // swap the instance as the previous callback list is being used asynchronously
+            callbacks = new LinkedList<IOCallback>();
+
+            buffer.clear();
+
+            bufferLimit = 0;
+
+            flushesDone.incrementAndGet();
+         }
+      }
+   }
+
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+   private class LogRatesTimerTask extends TimerTask
+   {
+      private boolean closed;
+
+      private long lastExecution;
+
+      private long lastBytesFlushed;
+
+      private long lastFlushesDone;
+
+      @Override
+      public synchronized void run()
+      {
+         if (!closed)
+         {
+            long now = System.currentTimeMillis();
+
+            long bytesF = bytesFlushed.get();
+            long flushesD = flushesDone.get();
+
+            if (lastExecution != 0)
+            {
+               double rate = 1000 * (double) (bytesF - lastBytesFlushed) / (now - lastExecution);
+               ActiveMQJournalLogger.LOGGER.writeRate(rate, (long) (rate / (1024 * 1024)));
+               double flushRate = 1000 * (double) (flushesD - lastFlushesDone) / (now - lastExecution);
+               ActiveMQJournalLogger.LOGGER.flushRate(flushRate);
+            }
+
+            lastExecution = now;
+
+            lastBytesFlushed = bytesF;
+
+            lastFlushesDone = flushesD;
+         }
+      }
+
+      @Override
+      public synchronized boolean cancel()
+      {
+         closed = true;
+
+         return super.cancel();
+      }
+   }
+
+   private class CheckTimer implements Runnable
+   {
+      private volatile boolean closed = false;
+
+      int checks = 0;
+      int failedChecks = 0;
+      long timeBefore = 0;
+
+      final int sleepMillis = timeout / 1000000; // truncates
+      final int sleepNanos = timeout % 1000000;
+
+
+      public void run()
+      {
+         long lastFlushTime = 0;
+
+         while (!closed)
+         {
+            // We flush on the timer if there are pending syncs there and we've waited at least one
+            // timeout since the time of the last flush.
+            // Effectively flushing "resets" the timer
+            // On the timeout verification, notice that we ignore the timeout check if we are using sleep
+
+            if (pendingSync)
+            {
+               if (isUseSleep())
+               {
+                  // if using sleep, we will always flush
+                  flush();
+                  lastFlushTime = System.nanoTime();
+               }
+               else if (bufferObserver != null && System.nanoTime() > lastFlushTime + timeout)
+               {
+                  // if not using flush we will spin and do the time checks manually
+                  flush();
+                  lastFlushTime = System.nanoTime();
+               }
+
+            }
+
+            sleepIfPossible();
+
+            try
+            {
+               spinLimiter.acquire();
+
+               Thread.yield();
+
+               spinLimiter.release();
+            }
+            catch (InterruptedException e)
+            {
+               throw new ActiveMQInterruptedException(e);
+            }
+         }
+      }
+
+      /**
+       * We will attempt to use sleep only if the system supports nano-sleep
+       * we will on that case verify up to MAX_CHECKS if nano sleep is behaving well.
+       * if more than 50% of the checks have failed we will cancel the sleep and just use regular spin
+       */
+      private void sleepIfPossible()
+      {
+         if (isUseSleep())
+         {
+            if (checks < MAX_CHECKS_ON_SLEEP)
+            {
+               timeBefore = System.nanoTime();
+            }
+
+            try
+            {
+               sleep(sleepMillis, sleepNanos);
+            }
+            catch (InterruptedException e)
+            {
+               throw new ActiveMQInterruptedException(e);
+            }
+            catch (Exception e)
+            {
+               setUseSleep(false);
+               ActiveMQJournalLogger.LOGGER.warn(e.getMessage() + ", disabling sleep on TimedBuffer, using spin now", e);
+            }
+
+            if (checks < MAX_CHECKS_ON_SLEEP)
+            {
+               long realTimeSleep = System.nanoTime() - timeBefore;
+
+               // I'm letting the real time to be up to 50% than the requested sleep.
+               if (realTimeSleep > timeout * 1.5)
+               {
+                  failedChecks++;
+               }
+
+               if (++checks >= MAX_CHECKS_ON_SLEEP)
+               {
+                  if (failedChecks > MAX_CHECKS_ON_SLEEP * 0.5)
+                  {
+                     ActiveMQJournalLogger.LOGGER.debug("Thread.sleep with nano seconds is not working as expected, Your kernel possibly doesn't support real time. the Journal TimedBuffer will spin for timeouts");
+                     setUseSleep(false);
+                  }
+               }
+            }
+         }
+      }
+
+      public void close()
+      {
+         closed = true;
+      }
+   }
+
+   /**
+    * Sub classes (tests basically) can use this to override how the sleep is being done
+    *
+    * @param sleepMillis
+    * @param sleepNanos
+    * @throws InterruptedException
+    */
+   protected void sleep(int sleepMillis, int sleepNanos) throws InterruptedException
+   {
+      Thread.sleep(sleepMillis, sleepNanos);
+   }
+
+   /**
+    * Sub classes (tests basically) can use this to override disabling spinning
+    */
+   protected void stopSpin()
+   {
+      if (spinning)
+      {
+         try
+         {
+            // We acquire the spinLimiter semaphore - this prevents the timer flush thread unnecessarily spinning
+            // when the buffer is inactive
+            spinLimiter.acquire();
+         }
+         catch (InterruptedException e)
+         {
+            throw new ActiveMQInterruptedException(e);
+         }
+
+         spinning = false;
+      }
+   }
+
+
+   /**
+    * Sub classes (tests basically) can use this to override disabling spinning
+    */
+   protected void startSpin()
+   {
+      if (!spinning)
+      {
+         spinLimiter.release();
+
+         spinning = true;
+      }
+   }
+
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBufferObserver.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBufferObserver.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBufferObserver.java
new file mode 100644
index 0000000..7a9659f
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBufferObserver.java
@@ -0,0 +1,53 @@
+/*
+ * 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.activemq.artemis.core.io.buffer;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.apache.activemq.artemis.core.io.IOCallback;
+
+
+public interface TimedBufferObserver
+{
+
+   // Constants -----------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
+   // Static --------------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   // Public --------------------------------------------------------
+
+   void flushBuffer(ByteBuffer buffer, boolean syncRequested, List<IOCallback> callbacks);
+
+   /** Return the number of remaining bytes that still fit on the observer (file) */
+   int getRemainingBytes();
+
+   ByteBuffer newBuffer(int size, int limit);
+
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFile.java
new file mode 100644
index 0000000..d20045e
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFile.java
@@ -0,0 +1,393 @@
+/*
+ * 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.activemq.artemis.core.io.nio;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
+import org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.AbstractSequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.journal.ActiveMQJournalBundle;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+
+public final class NIOSequentialFile extends AbstractSequentialFile
+{
+   private FileChannel channel;
+
+   private RandomAccessFile rfile;
+
+   /**
+    * The write semaphore here is only used when writing asynchronously
+    */
+   private Semaphore maxIOSemaphore;
+
+   private final int defaultMaxIO;
+
+   private int maxIO;
+
+   public NIOSequentialFile(final SequentialFileFactory factory,
+                            final File directory,
+                            final String file,
+                            final int maxIO,
+                            final Executor writerExecutor)
+   {
+      super(directory, file, factory, writerExecutor);
+      defaultMaxIO = maxIO;
+   }
+
+   public int getAlignment()
+   {
+      return 1;
+   }
+
+   public int calculateBlockStart(final int position)
+   {
+      return position;
+   }
+
+   public synchronized boolean isOpen()
+   {
+      return channel != null;
+   }
+
+   /**
+    * this.maxIO represents the default maxIO.
+    * Some operations while initializing files on the journal may require a different maxIO
+    */
+   public synchronized void open() throws IOException
+   {
+      open(defaultMaxIO, true);
+   }
+
+   public void open(final int maxIO, final boolean useExecutor) throws IOException
+   {
+      try
+      {
+         rfile = new RandomAccessFile(getFile(), "rw");
+
+         channel = rfile.getChannel();
+
+         fileSize = channel.size();
+      }
+      catch (IOException e)
+      {
+         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+         throw e;
+      }
+
+      if (writerExecutor != null && useExecutor)
+      {
+         maxIOSemaphore = new Semaphore(maxIO);
+         this.maxIO = maxIO;
+      }
+   }
+
+   public void fill(final int size) throws IOException
+   {
+      ByteBuffer bb = ByteBuffer.allocate(size);
+
+      bb.limit(size);
+      bb.position(0);
+
+      try
+      {
+         channel.position(0);
+         channel.write(bb);
+         channel.force(false);
+         channel.position(0);
+      }
+      catch (IOException e)
+      {
+         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+         throw e;
+      }
+
+      fileSize = channel.size();
+   }
+
+   @Override
+   public synchronized void close() throws IOException, InterruptedException, ActiveMQException
+   {
+      super.close();
+
+      if (maxIOSemaphore != null)
+      {
+         while (!maxIOSemaphore.tryAcquire(maxIO, 60, TimeUnit.SECONDS))
+         {
+            ActiveMQJournalLogger.LOGGER.errorClosingFile(getFileName());
+         }
+      }
+
+      maxIOSemaphore = null;
+      try
+      {
+         if (channel != null)
+         {
+            channel.close();
+         }
+
+         if (rfile != null)
+         {
+            rfile.close();
+         }
+      }
+      catch (IOException e)
+      {
+         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+         throw e;
+      }
+      channel = null;
+
+      rfile = null;
+
+      notifyAll();
+   }
+
+   public int read(final ByteBuffer bytes) throws Exception
+   {
+      return read(bytes, null);
+   }
+
+   public synchronized int read(final ByteBuffer bytes, final IOCallback callback) throws IOException,
+      ActiveMQIllegalStateException
+   {
+      try
+      {
+         if (channel == null)
+         {
+            throw new ActiveMQIllegalStateException("File " + this.getFileName() + " has a null channel");
+         }
+         int bytesRead = channel.read(bytes);
+
+         if (callback != null)
+         {
+            callback.done();
+         }
+
+         bytes.flip();
+
+         return bytesRead;
+      }
+      catch (IOException e)
+      {
+         if (callback != null)
+         {
+            callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getLocalizedMessage());
+         }
+
+         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+
+         throw e;
+      }
+   }
+
+   public void sync() throws IOException
+   {
+      if (channel != null)
+      {
+         try
+         {
+            channel.force(false);
+         }
+         catch (IOException e)
+         {
+            factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+            throw e;
+         }
+      }
+   }
+
+   public long size() throws IOException
+   {
+      if (channel == null)
+      {
+         return getFile().length();
+      }
+
+      try
+      {
+         return channel.size();
+      }
+      catch (IOException e)
+      {
+         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+         throw e;
+      }
+   }
+
+   @Override
+   public void position(final long pos) throws IOException
+   {
+      try
+      {
+         super.position(pos);
+         channel.position(pos);
+      }
+      catch (IOException e)
+      {
+         factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+         throw e;
+      }
+   }
+
+   @Override
+   public String toString()
+   {
+      return "NIOSequentialFile " + getFile();
+   }
+
+   public SequentialFile cloneFile()
+   {
+      return new NIOSequentialFile(factory, directory, getFileName(), maxIO, writerExecutor);
+   }
+
+   public void writeDirect(final ByteBuffer bytes, final boolean sync, final IOCallback callback)
+   {
+      if (callback == null)
+      {
+         throw new NullPointerException("callback parameter need to be set");
+      }
+
+      try
+      {
+         internalWrite(bytes, sync, callback);
+      }
+      catch (Exception e)
+      {
+         callback.onError(ActiveMQExceptionType.GENERIC_EXCEPTION.getCode(), e.getMessage());
+      }
+   }
+
+   public void writeDirect(final ByteBuffer bytes, final boolean sync) throws Exception
+   {
+      internalWrite(bytes, sync, null);
+   }
+
+   public void writeInternal(final ByteBuffer bytes) throws Exception
+   {
+      internalWrite(bytes, true, null);
+   }
+
+   @Override
+   protected ByteBuffer newBuffer(int size, final int limit)
+   {
+      // For NIO, we don't need to allocate a buffer the entire size of the timed buffer, unlike AIO
+
+      size = limit;
+
+      return super.newBuffer(size, limit);
+   }
+
+   private void internalWrite(final ByteBuffer bytes, final boolean sync, final IOCallback callback) throws IOException, ActiveMQIOErrorException, InterruptedException
+   {
+      if (!isOpen())
+      {
+         if (callback != null)
+         {
+            callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), "File not opened");
+         }
+         else
+         {
+            throw ActiveMQJournalBundle.BUNDLE.fileNotOpened();
+         }
+         return;
+      }
+
+      position.addAndGet(bytes.limit());
+
+      if (maxIOSemaphore == null || callback == null)
+      {
+         // if maxIOSemaphore == null, that means we are not using executors and the writes are synchronous
+         try
+         {
+            doInternalWrite(bytes, sync, callback);
+         }
+         catch (IOException e)
+         {
+            factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+         }
+      }
+      else
+      {
+         // This is a flow control on writing, just like maxAIO on libaio
+         maxIOSemaphore.acquire();
+
+         writerExecutor.execute(new Runnable()
+         {
+            public void run()
+            {
+               try
+               {
+                  try
+                  {
+                     doInternalWrite(bytes, sync, callback);
+                  }
+                  catch (IOException e)
+                  {
+                     ActiveMQJournalLogger.LOGGER.errorSubmittingWrite(e);
+                     factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), NIOSequentialFile.this);
+                     callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getMessage());
+                  }
+                  catch (Throwable e)
+                  {
+                     ActiveMQJournalLogger.LOGGER.errorSubmittingWrite(e);
+                     callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getMessage());
+                  }
+               }
+               finally
+               {
+                  maxIOSemaphore.release();
+               }
+            }
+         });
+      }
+   }
+
+   /**
+    * @param bytes
+    * @param sync
+    * @param callback
+    * @throws IOException
+    * @throws Exception
+    */
+   private void doInternalWrite(final ByteBuffer bytes, final boolean sync, final IOCallback callback) throws IOException
+   {
+      channel.write(bytes);
+
+      if (sync)
+      {
+         sync();
+      }
+
+      if (callback != null)
+      {
+         callback.done();
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFileFactory.java
new file mode 100644
index 0000000..e64e405
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFileFactory.java
@@ -0,0 +1,168 @@
+/*
+ * 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.activemq.artemis.core.io.nio;
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+
+import org.apache.activemq.artemis.core.io.AbstractSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
+
+public class NIOSequentialFileFactory extends AbstractSequentialFileFactory
+{
+   public NIOSequentialFileFactory(final File journalDir, final int maxIO)
+   {
+      this(journalDir, null, maxIO);
+   }
+
+   public NIOSequentialFileFactory(final File journalDir, final IOCriticalErrorListener listener, final int maxIO)
+   {
+      this(journalDir,
+           false,
+           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO,
+           JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO,
+           maxIO,
+           false,
+           listener);
+   }
+
+   public NIOSequentialFileFactory(final File journalDir, final boolean buffered, final int maxIO)
+   {
+      this(journalDir, buffered, null, maxIO);
+   }
+
+   public NIOSequentialFileFactory(final File journalDir,
+                                   final boolean buffered,
+                                   final IOCriticalErrorListener listener, final int maxIO)
+   {
+      this(journalDir,
+           buffered,
+           JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO,
+           JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO,
+           maxIO,
+           false,
+           listener);
+   }
+
+   public NIOSequentialFileFactory(final File journalDir,
+                                   final boolean buffered,
+                                   final int bufferSize,
+                                   final int bufferTimeout,
+                                   final int maxIO,
+                                   final boolean logRates)
+   {
+      this(journalDir, buffered, bufferSize, bufferTimeout, maxIO, logRates, null);
+   }
+
+   public NIOSequentialFileFactory(final File journalDir,
+                                   final boolean buffered,
+                                   final int bufferSize,
+                                   final int bufferTimeout,
+                                   final int maxIO,
+                                   final boolean logRates,
+                                   final IOCriticalErrorListener listener)
+   {
+      super(journalDir, buffered, bufferSize, bufferTimeout, maxIO, logRates, listener);
+   }
+
+   public SequentialFile createSequentialFile(final String fileName)
+   {
+      return new NIOSequentialFile(this, journalDir, fileName, maxIO, writeExecutor);
+   }
+
+   public boolean isSupportsCallbacks()
+   {
+      return timedBuffer != null;
+   }
+
+
+   public ByteBuffer allocateDirectBuffer(final int size)
+   {
+      // Using direct buffer, as described on https://jira.jboss.org/browse/HORNETQ-467
+      ByteBuffer buffer2 = null;
+      try
+      {
+         buffer2 = ByteBuffer.allocateDirect(size);
+      }
+      catch (OutOfMemoryError error)
+      {
+         // This is a workaround for the way the JDK will deal with native buffers.
+         // the main portion is outside of the VM heap
+         // and the JDK will not have any reference about it to take GC into account
+         // so we force a GC and try again.
+         WeakReference<Object> obj = new WeakReference<Object>(new Object());
+         try
+         {
+            long timeout = System.currentTimeMillis() + 5000;
+            while (System.currentTimeMillis() > timeout && obj.get() != null)
+            {
+               System.gc();
+               Thread.sleep(100);
+            }
+         }
+         catch (InterruptedException e)
+         {
+         }
+
+         buffer2 = ByteBuffer.allocateDirect(size);
+
+      }
+      return buffer2;
+   }
+
+   public void releaseDirectBuffer(ByteBuffer buffer)
+   {
+      // nothing we can do on this case. we can just have good faith on GC
+   }
+
+   public ByteBuffer newBuffer(final int size)
+   {
+      return ByteBuffer.allocate(size);
+   }
+
+   public void clearBuffer(final ByteBuffer buffer)
+   {
+      final int limit = buffer.limit();
+      buffer.rewind();
+
+      for (int i = 0; i < limit; i++)
+      {
+         buffer.put((byte)0);
+      }
+
+      buffer.rewind();
+   }
+
+   public ByteBuffer wrapBuffer(final byte[] bytes)
+   {
+      return ByteBuffer.wrap(bytes);
+   }
+
+   public int getAlignment()
+   {
+      return 1;
+   }
+
+   public int calculateBlockSize(final int bytes)
+   {
+      return bytes;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOAsyncTask.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOAsyncTask.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOAsyncTask.java
deleted file mode 100644
index 09c80ca..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOAsyncTask.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal;
-
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-
-/**
- * This class is just a direct extension of AIOCallback.
- * Just to avoid the direct dependency of org.apache.activemq.artemis.core.asynciio.AIOCallback from the journal.
- */
-public interface IOAsyncTask extends AIOCallback
-{
-}


[5/9] activemq-artemis git commit: ARTEMIS-163 First pass on the native AIO refactoring

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/SyncSpeedTest.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/SyncSpeedTest.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/SyncSpeedTest.java
deleted file mode 100644
index 0c982dc..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/SyncSpeedTest.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executors;
-
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-/**
- * A SyncSpeedTest
- *
- * This class just provides some diagnostics on how fast your disk can sync
- * Useful when determining performance issues
- */
-public class SyncSpeedTest
-{
-   public static void main(final String[] args)
-   {
-      try
-      {
-         new SyncSpeedTest().testScaleAIO();
-      }
-      catch (Exception e)
-      {
-         e.printStackTrace();
-      }
-   }
-
-   protected SequentialFileFactory fileFactory;
-
-   public boolean AIO = true;
-
-   protected void setupFactory()
-   {
-      if (AIO)
-      {
-         fileFactory = new AIOSequentialFileFactory(new File("."), 0, 0, false, null);
-      }
-      else
-      {
-         fileFactory = new NIOSequentialFileFactory(new File("."), false, 0, 0, false, null);
-      }
-   }
-
-   protected SequentialFile createSequentialFile(final String fileName)
-   {
-      if (AIO)
-      {
-         return new AIOSequentialFile(fileFactory,
-                                      0,
-                                      0,
-                                      new File("."),
-                                      fileName,
-                                      100000,
-                                      null,
-                                      null,
-                                      Executors.newSingleThreadExecutor());
-      }
-      else
-      {
-         return new NIOSequentialFile(fileFactory, new File("."), fileName, 1000, null);
-      }
-   }
-
-   public void run2() throws Exception
-   {
-      setupFactory();
-
-      int recordSize = 128 * 1024;
-
-      while (true)
-      {
-         System.out.println("** record size is " + recordSize);
-
-         int warmup = 500;
-
-         int its = 500;
-
-         int fileSize = (its + warmup) * recordSize;
-
-         SequentialFile file = createSequentialFile("sync-speed-test.dat");
-
-         if (file.exists())
-         {
-            file.delete();
-         }
-
-         file.open();
-
-         file.fill(0, fileSize, (byte)'X');
-
-         if (!AIO)
-         {
-            file.sync();
-         }
-
-         ByteBuffer bb1 = generateBuffer(recordSize, (byte)'h');
-
-         long start = 0;
-
-         for (int i = 0; i < its + warmup; i++)
-         {
-            if (i == warmup)
-            {
-               start = System.currentTimeMillis();
-            }
-
-            bb1.rewind();
-
-            file.writeDirect(bb1, true);
-         }
-
-         long end = System.currentTimeMillis();
-
-         double rate = 1000 * (double)its / (end - start);
-
-         double throughput = recordSize * rate;
-
-         System.out.println("Rate of " + rate + " syncs per sec");
-         System.out.println("Throughput " + throughput + " bytes per sec");
-         System.out.println("*************");
-
-         recordSize *= 2;
-      }
-   }
-
-   public void run() throws Exception
-   {
-      int recordSize = 256;
-
-      while (true)
-      {
-         System.out.println("** record size is " + recordSize);
-
-         int warmup = 500;
-
-         int its = 500;
-
-         int fileSize = (its + warmup) * recordSize;
-
-         File file = new File("sync-speed-test.dat");
-
-         if (file.exists())
-         {
-            if (!file.delete())
-            {
-               ActiveMQJournalLogger.LOGGER.errorDeletingFile(file);
-            }
-         }
-
-         boolean created = file.createNewFile();
-         if (!created)
-            throw new IOException("could not create file " + file);
-
-         RandomAccessFile rfile = new RandomAccessFile(file, "rw");
-
-         FileChannel channel = rfile.getChannel();
-
-         ByteBuffer bb = generateBuffer(fileSize, (byte)'x');
-
-         write(bb, channel, fileSize);
-
-         channel.force(true);
-
-         channel.position(0);
-
-         ByteBuffer bb1 = generateBuffer(recordSize, (byte)'h');
-
-         long start = 0;
-
-         for (int i = 0; i < its + warmup; i++)
-         {
-            if (i == warmup)
-            {
-               start = System.currentTimeMillis();
-            }
-
-            bb1.flip();
-            channel.write(bb1);
-            channel.force(false);
-         }
-
-         long end = System.currentTimeMillis();
-
-         double rate = 1000 * (double)its / (end - start);
-
-         double throughput = recordSize * rate;
-
-         System.out.println("Rate of " + rate + " syncs per sec");
-         System.out.println("Throughput " + throughput + " bytes per sec");
-
-         recordSize *= 2;
-      }
-   }
-
-   public void testScaleAIO() throws Exception
-   {
-      setupFactory();
-
-      final int recordSize = 1024;
-
-      System.out.println("** record size is " + recordSize);
-
-      final int its = 10;
-
-      for (int numThreads = 1; numThreads <= 10; numThreads++)
-      {
-
-         int fileSize = its * recordSize * numThreads;
-
-         final SequentialFile file = createSequentialFile("sync-speed-test.dat");
-
-         if (file.exists())
-         {
-            file.delete();
-         }
-
-         file.open();
-
-         file.fill(0, fileSize, (byte)'X');
-
-         if (!AIO)
-         {
-            file.sync();
-         }
-
-         final CountDownLatch latch = new CountDownLatch(its * numThreads);
-
-         class MyIOAsyncTask implements IOAsyncTask
-         {
-            public void done()
-            {
-               latch.countDown();
-            }
-
-            public void onError(final int errorCode, final String errorMessage)
-            {
-
-            }
-         }
-
-         final MyIOAsyncTask task = new MyIOAsyncTask();
-
-         class MyRunner implements Runnable
-         {
-            private final ByteBuffer bb1;
-
-            MyRunner()
-            {
-               bb1 = generateBuffer(recordSize, (byte)'h');
-            }
-
-            public void run()
-            {
-               for (int i = 0; i < its; i++)
-               {
-                  bb1.rewind();
-
-                  file.writeDirect(bb1, true, task);
-                  // try
-                  // {
-                  // file.writeDirect(bb1, true);
-                  // }
-                  // catch (Exception e)
-                  // {
-                  // e.printStackTrace();
-                  // }
-               }
-            }
-         }
-
-         Set<Thread> threads = new HashSet<Thread>();
-
-         for (int i = 0; i < numThreads; i++)
-         {
-            MyRunner runner = new MyRunner();
-
-            Thread t = new Thread(runner);
-
-            threads.add(t);
-         }
-
-         long start = System.currentTimeMillis();
-
-         for (Thread t : threads)
-         {
-            ActiveMQJournalLogger.LOGGER.startingThread();
-            t.start();
-         }
-
-         for (Thread t : threads)
-         {
-            t.join();
-         }
-
-         latch.await();
-
-         long end = System.currentTimeMillis();
-
-         double rate = 1000 * (double)its * numThreads / (end - start);
-
-         double throughput = recordSize * rate;
-
-         System.out.println("For " + numThreads + " threads:");
-         System.out.println("Rate of " + rate + " records per sec");
-         System.out.println("Throughput " + throughput + " bytes per sec");
-         System.out.println("*************");
-      }
-   }
-
-   private void write(final ByteBuffer buffer, final FileChannel channel, final int size) throws Exception
-   {
-      buffer.flip();
-
-      channel.write(buffer);
-   }
-
-   private ByteBuffer generateBuffer(final int size, final byte ch)
-   {
-      ByteBuffer bb = ByteBuffer.allocateDirect(size);
-
-      for (int i = 0; i < size; i++)
-      {
-         bb.put(ch);
-      }
-
-      return bb;
-   }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBuffer.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBuffer.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBuffer.java
deleted file mode 100644
index 45d4b62..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBuffer.java
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
-import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-public class TimedBuffer
-{
-   // Constants -----------------------------------------------------
-
-   // The number of tries on sleep before switching to spin
-   public static final int MAX_CHECKS_ON_SLEEP = 20;
-
-   // Attributes ----------------------------------------------------
-
-   private TimedBufferObserver bufferObserver;
-
-   // If the TimedBuffer is idle - i.e. no records are being added, then it's pointless the timer flush thread
-   // in spinning and checking the time - and using up CPU in the process - this semaphore is used to
-   // prevent that
-   private final Semaphore spinLimiter = new Semaphore(1);
-
-   private CheckTimer timerRunnable = new CheckTimer();
-
-   private final int bufferSize;
-
-   private final ActiveMQBuffer buffer;
-
-   private int bufferLimit = 0;
-
-   private List<IOAsyncTask> callbacks;
-
-   private volatile int timeout;
-
-   // used to measure sync requests. When a sync is requested, it shouldn't take more than timeout to happen
-   private volatile boolean pendingSync = false;
-
-   private Thread timerThread;
-
-   private volatile boolean started;
-
-   // We use this flag to prevent flush occurring between calling checkSize and addBytes
-   // CheckSize must always be followed by it's corresponding addBytes otherwise the buffer
-   // can get in an inconsistent state
-   private boolean delayFlush;
-
-   // for logging write rates
-
-   private final boolean logRates;
-
-   private final AtomicLong bytesFlushed = new AtomicLong(0);
-
-   private final AtomicLong flushesDone = new AtomicLong(0);
-
-   private Timer logRatesTimer;
-
-   private TimerTask logRatesTimerTask;
-
-   private boolean useSleep = true;
-
-   // no need to be volatile as every access is synchronized
-   private boolean spinning = false;
-
-   // Static --------------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   // Public --------------------------------------------------------
-
-   public TimedBuffer(final int size, final int timeout, final boolean logRates)
-   {
-      bufferSize = size;
-
-      this.logRates = logRates;
-
-      if (logRates)
-      {
-         logRatesTimer = new Timer(true);
-      }
-      // Setting the interval for nano-sleeps
-
-      buffer = ActiveMQBuffers.fixedBuffer(bufferSize);
-
-      buffer.clear();
-
-      bufferLimit = 0;
-
-      callbacks = new ArrayList<IOAsyncTask>();
-
-      this.timeout = timeout;
-   }
-
-   // for Debug purposes
-   public synchronized boolean isUseSleep()
-   {
-      return useSleep;
-   }
-
-   public synchronized void setUseSleep(boolean useSleep)
-   {
-      this.useSleep = useSleep;
-   }
-
-   public synchronized void start()
-   {
-      if (started)
-      {
-         return;
-      }
-
-      // Need to start with the spin limiter acquired
-      try
-      {
-         spinLimiter.acquire();
-      }
-      catch (InterruptedException e)
-      {
-         throw new ActiveMQInterruptedException(e);
-      }
-
-      timerRunnable = new CheckTimer();
-
-      timerThread = new Thread(timerRunnable, "activemq-buffer-timeout");
-
-      timerThread.start();
-
-      if (logRates)
-      {
-         logRatesTimerTask = new LogRatesTimerTask();
-
-         logRatesTimer.scheduleAtFixedRate(logRatesTimerTask, 2000, 2000);
-      }
-
-      started = true;
-   }
-
-   public void stop()
-   {
-      if (!started)
-      {
-         return;
-      }
-
-      flush();
-
-      bufferObserver = null;
-
-      timerRunnable.close();
-
-      spinLimiter.release();
-
-      if (logRates)
-      {
-         logRatesTimerTask.cancel();
-      }
-
-      while (timerThread.isAlive())
-      {
-         try
-         {
-            timerThread.join();
-         }
-         catch (InterruptedException e)
-         {
-            throw new ActiveMQInterruptedException(e);
-         }
-      }
-
-      started = false;
-   }
-
-   public synchronized void setObserver(final TimedBufferObserver observer)
-   {
-      if (bufferObserver != null)
-      {
-         flush();
-      }
-
-      bufferObserver = observer;
-   }
-
-   /**
-    * Verify if the size fits the buffer
-    *
-    * @param sizeChecked
-    */
-   public synchronized boolean checkSize(final int sizeChecked)
-   {
-      if (!started)
-      {
-         throw new IllegalStateException("TimedBuffer is not started");
-      }
-
-      if (sizeChecked > bufferSize)
-      {
-         throw new IllegalStateException("Can't write records bigger than the bufferSize(" + bufferSize +
-                                            ") on the journal");
-      }
-
-      if (bufferLimit == 0 || buffer.writerIndex() + sizeChecked > bufferLimit)
-      {
-         // Either there is not enough space left in the buffer for the sized record
-         // Or a flush has just been performed and we need to re-calcualate bufferLimit
-
-         flush();
-
-         delayFlush = true;
-
-         final int remainingInFile = bufferObserver.getRemainingBytes();
-
-         if (sizeChecked > remainingInFile)
-         {
-            return false;
-         }
-         else
-         {
-            // There is enough space in the file for this size
-
-            // Need to re-calculate buffer limit
-
-            bufferLimit = Math.min(remainingInFile, bufferSize);
-
-            return true;
-         }
-      }
-      else
-      {
-         delayFlush = true;
-
-         return true;
-      }
-   }
-
-   public synchronized void addBytes(final ActiveMQBuffer bytes, final boolean sync, final IOAsyncTask callback)
-   {
-      addBytes(new ByteArrayEncoding(bytes.toByteBuffer().array()), sync, callback);
-   }
-
-   public synchronized void addBytes(final EncodingSupport bytes, final boolean sync, final IOAsyncTask callback)
-   {
-      if (!started)
-      {
-         throw new IllegalStateException("TimedBuffer is not started");
-      }
-
-      delayFlush = false;
-
-      bytes.encode(buffer);
-
-      callbacks.add(callback);
-
-      if (sync)
-      {
-         pendingSync = true;
-
-         startSpin();
-      }
-
-   }
-
-   public void flush()
-   {
-      flush(false);
-   }
-
-   /**
-    * force means the Journal is moving to a new file. Any pending write need to be done immediately
-    * or data could be lost
-    */
-   public void flush(final boolean force)
-   {
-      synchronized (this)
-      {
-         if (!started)
-         {
-            throw new IllegalStateException("TimedBuffer is not started");
-         }
-
-         if ((force || !delayFlush) && buffer.writerIndex() > 0)
-         {
-            int pos = buffer.writerIndex();
-
-            if (logRates)
-            {
-               bytesFlushed.addAndGet(pos);
-            }
-
-            ByteBuffer bufferToFlush = bufferObserver.newBuffer(bufferSize, pos);
-
-            // Putting a byteArray on a native buffer is much faster, since it will do in a single native call.
-            // Using bufferToFlush.put(buffer) would make several append calls for each byte
-            // We also transfer the content of this buffer to the native file's buffer
-
-            bufferToFlush.put(buffer.toByteBuffer().array(), 0, pos);
-
-            bufferObserver.flushBuffer(bufferToFlush, pendingSync, callbacks);
-
-            stopSpin();
-
-            pendingSync = false;
-
-            // swap the instance as the previous callback list is being used asynchronously
-            callbacks = new LinkedList<IOAsyncTask>();
-
-            buffer.clear();
-
-            bufferLimit = 0;
-
-            flushesDone.incrementAndGet();
-         }
-      }
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-   private class LogRatesTimerTask extends TimerTask
-   {
-      private boolean closed;
-
-      private long lastExecution;
-
-      private long lastBytesFlushed;
-
-      private long lastFlushesDone;
-
-      @Override
-      public synchronized void run()
-      {
-         if (!closed)
-         {
-            long now = System.currentTimeMillis();
-
-            long bytesF = bytesFlushed.get();
-            long flushesD = flushesDone.get();
-
-            if (lastExecution != 0)
-            {
-               double rate = 1000 * (double) (bytesF - lastBytesFlushed) / (now - lastExecution);
-               ActiveMQJournalLogger.LOGGER.writeRate(rate, (long) (rate / (1024 * 1024)));
-               double flushRate = 1000 * (double) (flushesD - lastFlushesDone) / (now - lastExecution);
-               ActiveMQJournalLogger.LOGGER.flushRate(flushRate);
-            }
-
-            lastExecution = now;
-
-            lastBytesFlushed = bytesF;
-
-            lastFlushesDone = flushesD;
-         }
-      }
-
-      @Override
-      public synchronized boolean cancel()
-      {
-         closed = true;
-
-         return super.cancel();
-      }
-   }
-
-   private class CheckTimer implements Runnable
-   {
-      private volatile boolean closed = false;
-
-      int checks = 0;
-      int failedChecks = 0;
-      long timeBefore = 0;
-
-      final int sleepMillis = timeout / 1000000; // truncates
-      final int sleepNanos = timeout % 1000000;
-
-
-      public void run()
-      {
-         long lastFlushTime = 0;
-
-         while (!closed)
-         {
-            // We flush on the timer if there are pending syncs there and we've waited at least one
-            // timeout since the time of the last flush.
-            // Effectively flushing "resets" the timer
-            // On the timeout verification, notice that we ignore the timeout check if we are using sleep
-
-            if (pendingSync)
-            {
-               if (isUseSleep())
-               {
-                  // if using sleep, we will always flush
-                  flush();
-                  lastFlushTime = System.nanoTime();
-               }
-               else if (bufferObserver != null && System.nanoTime() > lastFlushTime + timeout)
-               {
-                  // if not using flush we will spin and do the time checks manually
-                  flush();
-                  lastFlushTime = System.nanoTime();
-               }
-
-            }
-
-            sleepIfPossible();
-
-            try
-            {
-               spinLimiter.acquire();
-
-               Thread.yield();
-
-               spinLimiter.release();
-            }
-            catch (InterruptedException e)
-            {
-               throw new ActiveMQInterruptedException(e);
-            }
-         }
-      }
-
-      /**
-       * We will attempt to use sleep only if the system supports nano-sleep
-       * we will on that case verify up to MAX_CHECKS if nano sleep is behaving well.
-       * if more than 50% of the checks have failed we will cancel the sleep and just use regular spin
-       */
-      private void sleepIfPossible()
-      {
-         if (isUseSleep())
-         {
-            if (checks < MAX_CHECKS_ON_SLEEP)
-            {
-               timeBefore = System.nanoTime();
-            }
-
-            try
-            {
-               sleep(sleepMillis, sleepNanos);
-            }
-            catch (InterruptedException e)
-            {
-               throw new ActiveMQInterruptedException(e);
-            }
-            catch (Exception e)
-            {
-               setUseSleep(false);
-               ActiveMQJournalLogger.LOGGER.warn(e.getMessage() + ", disabling sleep on TimedBuffer, using spin now", e);
-            }
-
-            if (checks < MAX_CHECKS_ON_SLEEP)
-            {
-               long realTimeSleep = System.nanoTime() - timeBefore;
-
-               // I'm letting the real time to be up to 50% than the requested sleep.
-               if (realTimeSleep > timeout * 1.5)
-               {
-                  failedChecks++;
-               }
-
-               if (++checks >= MAX_CHECKS_ON_SLEEP)
-               {
-                  if (failedChecks > MAX_CHECKS_ON_SLEEP * 0.5)
-                  {
-                     ActiveMQJournalLogger.LOGGER.debug("Thread.sleep with nano seconds is not working as expected, Your kernel possibly doesn't support real time. the Journal TimedBuffer will spin for timeouts");
-                     setUseSleep(false);
-                  }
-               }
-            }
-         }
-      }
-
-      public void close()
-      {
-         closed = true;
-      }
-   }
-
-   /**
-    * Sub classes (tests basically) can use this to override how the sleep is being done
-    *
-    * @param sleepMillis
-    * @param sleepNanos
-    * @throws InterruptedException
-    */
-   protected void sleep(int sleepMillis, int sleepNanos) throws InterruptedException
-   {
-      Thread.sleep(sleepMillis, sleepNanos);
-   }
-
-   /**
-    * Sub classes (tests basically) can use this to override disabling spinning
-    */
-   protected void stopSpin()
-   {
-      if (spinning)
-      {
-         try
-         {
-            // We acquire the spinLimiter semaphore - this prevents the timer flush thread unnecessarily spinning
-            // when the buffer is inactive
-            spinLimiter.acquire();
-         }
-         catch (InterruptedException e)
-         {
-            throw new ActiveMQInterruptedException(e);
-         }
-
-         spinning = false;
-      }
-   }
-
-
-   /**
-    * Sub classes (tests basically) can use this to override disabling spinning
-    */
-   protected void startSpin()
-   {
-      if (!spinning)
-      {
-         spinLimiter.release();
-
-         spinning = true;
-      }
-   }
-
-
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBufferObserver.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBufferObserver.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBufferObserver.java
deleted file mode 100644
index f219f08..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBufferObserver.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.activemq.artemis.core.journal.impl;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-
-public interface TimedBufferObserver
-{
-
-   // Constants -----------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   // Static --------------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   // Public --------------------------------------------------------
-
-   void flushBuffer(ByteBuffer buffer, boolean syncRequested, List<IOAsyncTask> callbacks);
-
-   /** Return the number of remaining bytes that still fit on the observer (file) */
-   int getRemainingBytes();
-
-   ByteBuffer newBuffer(int size, int limit);
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java
index 4035202..140927e 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java
@@ -18,10 +18,10 @@ package org.apache.activemq.artemis.core.journal.impl;
 
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
 import org.apache.activemq.artemis.utils.ReusableLatch;
 
-public class TransactionCallback implements IOAsyncTask
+public class TransactionCallback implements IOCallback
 {
    private final ReusableLatch countLatch = new ReusableLatch();
 
@@ -33,7 +33,7 @@ public class TransactionCallback implements IOAsyncTask
 
    private int done = 0;
 
-   private volatile IOAsyncTask delegateCompletion;
+   private volatile IOCallback delegateCompletion;
 
    public void countUp()
    {
@@ -46,7 +46,7 @@ public class TransactionCallback implements IOAsyncTask
       countLatch.countDown();
       if (++done == up.get() && delegateCompletion != null)
       {
-         final IOAsyncTask delegateToCall = delegateCompletion;
+         final IOCallback delegateToCall = delegateCompletion;
          // We need to set the delegateCompletion to null first or blocking commits could miss a callback
          // What would affect mainly tests
          delegateCompletion = null;
@@ -81,7 +81,7 @@ public class TransactionCallback implements IOAsyncTask
    /**
     * @return the delegateCompletion
     */
-   public IOAsyncTask getDelegateCompletion()
+   public IOCallback getDelegateCompletion()
    {
       return delegateCompletion;
    }
@@ -89,7 +89,7 @@ public class TransactionCallback implements IOAsyncTask
    /**
     * @param delegateCompletion the delegateCompletion to set
     */
-   public void setDelegateCompletion(final IOAsyncTask delegateCompletion)
+   public void setDelegateCompletion(final IOCallback delegateCompletion)
    {
       this.delegateCompletion = delegateCompletion;
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/test/java/org/apache/activemq/artemis/core/io/aio/CallbackOrderTest.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/test/java/org/apache/activemq/artemis/core/io/aio/CallbackOrderTest.java b/artemis-journal/src/test/java/org/apache/activemq/artemis/core/io/aio/CallbackOrderTest.java
new file mode 100644
index 0000000..82d4502
--- /dev/null
+++ b/artemis-journal/src/test/java/org/apache/activemq/artemis/core/io/aio/CallbackOrderTest.java
@@ -0,0 +1,97 @@
+/**
+ * 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.activemq.artemis.core.io.aio;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/** This will emulate callbacks out of order from libaio*/
+public class CallbackOrderTest
+{
+
+   @Rule
+   public TemporaryFolder temporaryFolder;
+
+   public CallbackOrderTest()
+   {
+      File parent = new File("./target");
+      parent.mkdirs();
+      temporaryFolder = new TemporaryFolder(parent);
+   }
+
+   /** This method will make sure callbacks will come back in order even when out order from libaio */
+   @Test
+   public void testCallbackOutOfOrder() throws Exception
+   {
+      AIOSequentialFileFactory factory = new AIOSequentialFileFactory(temporaryFolder.getRoot(), 100);
+      AIOSequentialFile file = (AIOSequentialFile)factory.createSequentialFile("test.bin");
+
+      final AtomicInteger count = new AtomicInteger(0);
+
+      IOCallback callback = new IOCallback()
+      {
+         @Override
+         public void done()
+         {
+            count.incrementAndGet();
+         }
+
+         @Override
+         public void onError(int errorCode, String errorMessage)
+         {
+
+         }
+      };
+
+      ArrayList<AIOSequentialFileFactory.AIOSequentialCallback> list = new ArrayList<>();
+
+      // We will repeat the teset a few times, increasing N
+      // to increase possibility of issues due to reuse of callbacks
+      for (int n = 1; n < 100; n++)
+      {
+         System.out.println("n = " + n);
+         int N = n;
+         count.set(0);
+         list.clear();
+         for (int i = 0; i < N; i++)
+         {
+            list.add(file.getCallback(callback, null));
+         }
+
+
+         for (int i = N - 1; i >= 0; i--)
+         {
+            list.get(i).done();
+         }
+
+         Assert.assertEquals(N, count.get());
+         Assert.assertEquals(0, file.pendingCallbackList.size());
+         Assert.assertTrue(file.pendingCallbackList.isEmpty());
+      }
+
+      factory.stop();
+
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java
----------------------------------------------------------------------
diff --git a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java
index 78154b6..bae871e 100644
--- a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java
+++ b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java
@@ -250,6 +250,7 @@ public class ActiveMQCreatePlugin extends AbstractMojo
          add(listCommands, "--failover-on-shutdown");
       }
 
+      add(listCommands, "--no-sync-test");
       add(listCommands, "--verbose");
 
       add(listCommands, instance.getAbsolutePath());

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/bin/libartemis-native-32.so
----------------------------------------------------------------------
diff --git a/artemis-native/bin/libartemis-native-32.so b/artemis-native/bin/libartemis-native-32.so
index 7178069..df4b560 100755
Binary files a/artemis-native/bin/libartemis-native-32.so and b/artemis-native/bin/libartemis-native-32.so differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/bin/libartemis-native-64.so
----------------------------------------------------------------------
diff --git a/artemis-native/bin/libartemis-native-64.so b/artemis-native/bin/libartemis-native-64.so
index 1c4983c..aec757a 100755
Binary files a/artemis-native/bin/libartemis-native-64.so and b/artemis-native/bin/libartemis-native-64.so differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/pom.xml
----------------------------------------------------------------------
diff --git a/artemis-native/pom.xml b/artemis-native/pom.xml
index abd5f0d..0206166 100644
--- a/artemis-native/pom.xml
+++ b/artemis-native/pom.xml
@@ -32,6 +32,30 @@
          <artifactId>artemis-commons</artifactId>
          <version>${project.version}</version>
       </dependency>
+
+      <dependency>
+         <groupId>org.jboss.logging</groupId>
+         <artifactId>jboss-logging-processor</artifactId>
+         <scope>provided</scope>
+         <optional>true</optional>
+      </dependency>
+
+      <dependency>
+         <groupId>org.jboss.logging</groupId>
+         <artifactId>jboss-logging</artifactId>
+      </dependency>
+      <dependency>
+         <groupId>org.jboss.logmanager</groupId>
+         <artifactId>jboss-logmanager</artifactId>
+         <scope>test</scope>
+      </dependency>
+
+      <dependency>
+         <groupId>junit</groupId>
+         <artifactId>junit</artifactId>
+         <scope>test</scope>
+      </dependency>
+
    </dependencies>
 
    <build>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AIOController.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AIOController.cpp b/artemis-native/src/main/c/AIOController.cpp
deleted file mode 100644
index a61bf04..0000000
--- a/artemis-native/src/main/c/AIOController.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-  * 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.
-  */
-
-
-#include <string>
-#include "AIOController.h"
-#include "JavaUtilities.h"
-#include "JAIODatatypes.h"
-
-AIOController::AIOController(std::string fileName, int maxIO) : logger(0), fileOutput(fileName, this, maxIO) 
-{
-}
-
-void AIOController::log(THREAD_CONTEXT threadContext, short level, const char * message)
-{
-	jmethodID methodID = 0;
-	
-	switch (level)
-	{
-	case 0: methodID = loggerError; break;
-	case 1: methodID = loggerWarn; break;
-	case 2: methodID = loggerInfo; break;
-	case 3: methodID = loggerDebug; break;
-	default: methodID = loggerDebug; break;
-	}
-
-#ifdef DEBUG
-	fprintf (stderr,"Callig log methodID=%ld, message=%s, logger=%ld, threadContext = %ld\n", (long) methodID, message, (long) logger, (long) threadContext); fflush(stderr);
-#endif
-	threadContext->CallVoidMethod(logger,methodID,threadContext->NewStringUTF(message));
-}
-
-
-void AIOController::destroy(THREAD_CONTEXT context)
-{
-	if (logger != 0)
-	{
-		context->DeleteGlobalRef(logger);
-	}
-}
-
-/*
- * level = 0-error, 1-warn, 2-info, 3-debug
- */
-
-
-AIOController::~AIOController()
-{
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AIOController.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AIOController.h b/artemis-native/src/main/c/AIOController.h
deleted file mode 100644
index 913565f..0000000
--- a/artemis-native/src/main/c/AIOController.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-  * 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.
-  */
-
-
-#ifndef AIOCONTROLLER_H_
-#define AIOCONTROLLER_H_
-#include <jni.h>
-#include <string>
-#include "JAIODatatypes.h"
-#include "AsyncFile.h"
-
-class AIOController
-{
-public:
-	jmethodID done;
-	jmethodID error;
-
-	jobject logger;
-	
-	jmethodID loggerError;
-	jmethodID loggerWarn;
-	jmethodID loggerDebug;
-	jmethodID loggerInfo;
-
-	/*
-	 * level = 0-error, 1-warn, 2-info, 3-debug
-	 */
-	void log(THREAD_CONTEXT threadContext, short level, const char * message);
-	
-	AsyncFile fileOutput;
-	
-	void destroy(THREAD_CONTEXT context);
-	
-	AIOController(std::string fileName, int maxIO);
-	virtual ~AIOController();
-};
-#endif /*AIOCONTROLLER_H_*/

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AIOException.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AIOException.h b/artemis-native/src/main/c/AIOException.h
deleted file mode 100644
index 98745a2..0000000
--- a/artemis-native/src/main/c/AIOException.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-  * 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.
-  */
-
-
-
-#ifndef AIOEXCEPTION_H_
-#define AIOEXCEPTION_H_
-
-#include <exception>
-#include <string>
-
-
-#define NATIVE_ERROR_INTERNAL 200
-#define NATIVE_ERROR_INVALID_BUFFER 201
-#define NATIVE_ERROR_NOT_ALIGNED 202
-#define NATIVE_ERROR_CANT_INITIALIZE_AIO 203
-#define NATIVE_ERROR_CANT_RELEASE_AIO 204
-#define NATIVE_ERROR_CANT_OPEN_CLOSE_FILE 205
-#define NATIVE_ERROR_CANT_ALLOCATE_QUEUE 206
-#define NATIVE_ERROR_PREALLOCATE_FILE 208
-#define NATIVE_ERROR_ALLOCATE_MEMORY 209
-#define NATIVE_ERROR_IO 006
-#define NATIVE_ERROR_AIO_FULL 211
-
-
-class AIOException : public std::exception
-{
-private:
-	int errorCode;
-	std::string message;
-public:
-	AIOException(int _errorCode, std::string  _message) throw() : errorCode(_errorCode), message(_message)
-	{
-		errorCode = _errorCode;
-		message = _message;
-	}
-	
-	AIOException(int _errorCode, const char * _message) throw ()
-	{
-		message = std::string(_message);
-		errorCode = _errorCode;
-	}
-	
-	virtual ~AIOException() throw()
-	{
-		
-	}
-	
-	int inline getErrorCode()
-	{
-		return errorCode;
-	}
-	
-    const char* what() const throw()
-    {
-    	return message.data();
-    }
-	
-};
-
-#endif /*AIOEXCEPTION_H_*/

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AsyncFile.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AsyncFile.cpp b/artemis-native/src/main/c/AsyncFile.cpp
deleted file mode 100644
index 2385a0d..0000000
--- a/artemis-native/src/main/c/AsyncFile.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
-  * 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.
-  */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-
-#include <stdlib.h>
-#include <list>
-#include <iostream>
-#include <sstream>
-#include <memory.h>
-#include <errno.h>
-#include <libaio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include "AsyncFile.h"
-#include "AIOController.h"
-#include "AIOException.h"
-#include "pthread.h"
-#include "LockClass.h"
-#include "CallbackAdapter.h"
-#include "LockClass.h"
-
-//#define DEBUG
-
-#define WAIT_FOR_SPOT 10000
-#define TRIES_BEFORE_WARN 0
-#define TRIES_BEFORE_ERROR 500
-
-
-std::string io_error(int rc)
-{
-	std::stringstream buffer;
-
-	if (rc == -ENOSYS)
-		buffer << "AIO not in this kernel";
-	else
-		buffer << "Error:= " << strerror((int)-rc);
-
-	return buffer.str();
-}
-
-
-AsyncFile::AsyncFile(std::string & _fileName, AIOController * _controller, int _maxIO) : aioContext(0), events(0), fileHandle(0), controller(_controller), pollerRunning(0)
-{
-	::pthread_mutex_init(&fileMutex,0);
-	::pthread_mutex_init(&pollerMutex,0);
-
-	maxIO = _maxIO;
-	fileName = _fileName;
-	if (io_queue_init(maxIO, &aioContext))
-	{
-		throw AIOException(NATIVE_ERROR_CANT_INITIALIZE_AIO, "Can't initialize aio, out of AIO Handlers");
-	}
-
-	fileHandle = ::open(fileName.data(),  O_RDWR | O_CREAT | O_DIRECT, 0666);
-	if (fileHandle < 0)
-	{
-		io_queue_release(aioContext);
-		throw AIOException(NATIVE_ERROR_CANT_OPEN_CLOSE_FILE, "Can't open file");
-	}
-
-#ifdef DEBUG
-	fprintf (stderr,"File Handle %d", fileHandle);
-#endif
-
-	events = (struct io_event *)malloc (maxIO * sizeof (struct io_event));
-
-	if (events == 0)
-	{
-		throw AIOException (NATIVE_ERROR_CANT_ALLOCATE_QUEUE, "Can't allocate ioEvents");
-	}
-
-}
-
-AsyncFile::~AsyncFile()
-{
-	if (io_queue_release(aioContext))
-	{
-		throw AIOException(NATIVE_ERROR_CANT_RELEASE_AIO,"Can't release aio");
-	}
-	if (::close(fileHandle))
-	{
-		throw AIOException(NATIVE_ERROR_CANT_OPEN_CLOSE_FILE,"Can't close file");
-	}
-	free(events);
-	::pthread_mutex_destroy(&fileMutex);
-	::pthread_mutex_destroy(&pollerMutex);
-}
-
-int isException (THREAD_CONTEXT threadContext)
-{
-	return JNI_ENV(threadContext)->ExceptionOccurred() != 0;
-}
-
-void AsyncFile::pollEvents(THREAD_CONTEXT threadContext)
-{
-
-	LockClass lock(&pollerMutex);
-	pollerRunning=1;
-
-
-	while (pollerRunning)
-	{
-		if (isException(threadContext))
-		{
-			return;
-		}
-		int result = io_getevents(this->aioContext, 1, maxIO, events, 0);
-
-
-#ifdef DEBUG
-		fprintf (stderr, "poll, pollerRunning=%d\n", pollerRunning); fflush(stderr);
-#endif
-
-		if (result > 0)
-		{
-
-#ifdef DEBUG
-			fprintf (stdout, "Received %d events\n", result);
-			fflush(stdout);
-#endif
-		}
-
-		for (int i=0; i<result; i++)
-		{
-
-			struct iocb * iocbp = events[i].obj;
-
-			if (iocbp->data == (void *) -1)
-			{
-				pollerRunning = 0;
-#ifdef DEBUG
-				controller->log(threadContext, 2, "Received poller request to stop");
-#endif
-			}
-			else
-			{
-				CallbackAdapter * adapter = (CallbackAdapter *) iocbp->data;
-
-				long result = events[i].res;
-				if (result < 0)
-				{
-					std::string strerror = io_error((int)result);
-					adapter->onError(threadContext, result, strerror);
-				}
-				else
-				{
-					adapter->done(threadContext);
-				}
-			}
-
-			delete iocbp;
-		}
-	}
-#ifdef DEBUG
-	controller->log(threadContext, 2, "Poller finished execution");
-#endif
-}
-
-
-void AsyncFile::preAllocate(THREAD_CONTEXT , off_t position, int blocks, size_t size, int fillChar)
-{
-
-	if (size % ALIGNMENT != 0)
-	{
-		throw AIOException (NATIVE_ERROR_PREALLOCATE_FILE, "You can only pre allocate files in multiples of 512");
-	}
-
-	void * preAllocBuffer = 0;
-	if (posix_memalign(&preAllocBuffer, 512, size))
-	{
-		throw AIOException(NATIVE_ERROR_ALLOCATE_MEMORY, "Error on posix_memalign");
-	}
-
-	memset(preAllocBuffer, fillChar, size);
-
-
-	if (::lseek (fileHandle, position, SEEK_SET) < 0) throw AIOException (11, "Error positioning the file");
-
-	for (int i=0; i<blocks; i++)
-	{
-		if (::write(fileHandle, preAllocBuffer, size)<0)
-		{
-			throw AIOException (NATIVE_ERROR_PREALLOCATE_FILE, "Error pre allocating the file");
-		}
-	}
-
-	if (::lseek (fileHandle, position, SEEK_SET) < 0) throw AIOException (NATIVE_ERROR_IO, "Error positioning the file");
-
-	free (preAllocBuffer);
-}
-
-
-/** Write directly to the file without using libaio queue */
-void AsyncFile::writeInternal(THREAD_CONTEXT, long position, size_t size, void *& buffer)
-{
-	if (::lseek (fileHandle, position, SEEK_SET) < 0) throw AIOException (11, "Error positioning the file");
-
-	if (::write(fileHandle, buffer, size)<0)
-	{
-		throw AIOException (NATIVE_ERROR_IO, "Error writing file");
-	}
-	
-	if (::fsync(fileHandle) < 0)
-	{
-		throw AIOException (NATIVE_ERROR_IO, "Error on synchronizing file");
-	}
-	
-
-}
-
-
-void AsyncFile::write(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer, CallbackAdapter *& adapter)
-{
-
-	struct iocb * iocb = new struct iocb();
-	::io_prep_pwrite(iocb, fileHandle, buffer, size, position);
-	iocb->data = (void *) adapter;
-
-	int tries = 0;
-	int result = 0;
-
-	while ((result = ::io_submit(aioContext, 1, &iocb)) == (-EAGAIN))
-	{
-#ifdef DEBUG
-		fprintf (stderr, "Retrying block as iocb was full (retry=%d)\n", tries);
-#endif
-		tries ++;
-		if (tries > TRIES_BEFORE_WARN)
-		{
-#ifdef DEBUG
-		    fprintf (stderr, "Warning level on retries, informing logger (retry=%d)\n", tries);
-#endif
-			controller->log(threadContext, 1, "You should consider expanding AIOLimit if this message appears too many times");
-		}
-
-		if (tries > TRIES_BEFORE_ERROR)
-		{
-#ifdef DEBUG
-		    fprintf (stderr, "Error level on retries, throwing exception (retry=%d)\n", tries);
-#endif
-			throw AIOException(NATIVE_ERROR_AIO_FULL, "Too many retries (500) waiting for a valid iocb block, please increase MAX_IO limit");
-		}
-		::usleep(WAIT_FOR_SPOT);
-	}
-
-	if (result<0)
-	{
-		std::stringstream str;
-		str<< "Problem on submit block, errorCode=" << result;
-		throw AIOException (NATIVE_ERROR_IO, str.str());
-	}
-}
-
-void AsyncFile::read(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer, CallbackAdapter *& adapter)
-{
-
-	struct iocb * iocb = new struct iocb();
-	::io_prep_pread(iocb, fileHandle, buffer, size, position);
-	iocb->data = (void *) adapter;
-
-	int tries = 0;
-	int result = 0;
-
-	while ((result = ::io_submit(aioContext, 1, &iocb)) == (-EAGAIN))
-	{
-#ifdef DEBUG
-		fprintf (stderr, "Retrying block as iocb was full (retry=%d)\n", tries);
-#endif
-		tries ++;
-		if (tries > TRIES_BEFORE_WARN)
-		{
-#ifdef DEBUG
-		    fprintf (stderr, "Warning level on retries, informing logger (retry=%d)\n", tries);
-#endif
-			controller->log(threadContext, 1, "You should consider expanding AIOLimit if this message appears too many times");
-		}
-
-		if (tries > TRIES_BEFORE_ERROR)
-		{
-#ifdef DEBUG
-		    fprintf (stderr, "Error level on retries, throwing exception (retry=%d)\n", tries);
-#endif
-			throw AIOException(NATIVE_ERROR_AIO_FULL, "Too many retries (500) waiting for a valid iocb block, please increase MAX_IO limit");
-		}
-		::usleep(WAIT_FOR_SPOT);
-	}
-
-	if (result<0)
-	{
-		std::stringstream str;
-		str<< "Problem on submit block, errorCode=" << result;
-		throw AIOException (NATIVE_ERROR_IO, str.str());
-	}
-}
-
-long AsyncFile::getSize()
-{
-	struct stat statBuffer;
-
-	if (fstat(fileHandle, &statBuffer) < 0)
-	{
-		return -1l;
-	}
-	return statBuffer.st_size;
-}
-
-
-void AsyncFile::stopPoller(THREAD_CONTEXT threadContext)
-{
-	pollerRunning = 0;
-
-
-	struct iocb * iocb = new struct iocb();
-	::io_prep_pwrite(iocb, fileHandle, 0, 0, 0);
-	iocb->data = (void *) -1;
-
-	int result = 0;
-
-	while ((result = ::io_submit(aioContext, 1, &iocb)) == (-EAGAIN))
-	{
-		fprintf(stderr, "Couldn't send request to stop poller, trying again");
-		controller->log(threadContext, 1, "Couldn't send request to stop poller, trying again");
-		::usleep(WAIT_FOR_SPOT);
-	}
-
-	// Waiting the Poller to finish (by giving up the lock)
-	LockClass lock(&pollerMutex);
-}
-

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AsyncFile.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AsyncFile.h b/artemis-native/src/main/c/AsyncFile.h
deleted file mode 100644
index 71281c9..0000000
--- a/artemis-native/src/main/c/AsyncFile.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-  * 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.
-  */
-
-#ifndef FILEOUTPUT_H_
-#define FILEOUTPUT_H_
-
-#include <string>
-#include <libaio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include "JAIODatatypes.h"
-#include "AIOException.h"
-
-class AIOController;
-
-class CallbackAdapter;
-
-/** Author: Clebert Suconic at Redhat dot com*/
-class AsyncFile
-{
-private:
-	io_context_t aioContext;
-	struct io_event *events; 
-	int fileHandle;
-	std::string fileName;
-	
-	pthread_mutex_t fileMutex;
-	pthread_mutex_t pollerMutex;
-	
-	AIOController * controller;
-	
-	bool pollerRunning;
-	
-	int maxIO;
-	
-public:
-	AsyncFile(std::string & _fileName, AIOController * controller, int maxIO);
-	virtual ~AsyncFile();
-	
-	void write(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer, CallbackAdapter *& adapter);
-	
-	/** Write directly to the file without using libaio queue */
-	void writeInternal(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer);
-	
-	void read(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer, CallbackAdapter *& adapter);
-	
-	int getHandle()
-	{
-		return fileHandle;
-	}
-
-	long getSize();
-
-	inline void * newBuffer(int size)
-	{
-		void * buffer = 0;
-		if (::posix_memalign(&buffer, 512, size))
-		{
-			throw AIOException(NATIVE_ERROR_ALLOCATE_MEMORY, "Error on posix_memalign");
-		}
-		return buffer;
-		
-	}
-
-	inline void destroyBuffer(void * buffer)
-	{
-		::free(buffer);
-	}
-
-	
-	// Finishes the polling thread (if any) and return
-	void stopPoller(THREAD_CONTEXT threadContext);
-	void preAllocate(THREAD_CONTEXT threadContext, off_t position, int blocks, size_t size, int fillChar);
-	
-	void pollEvents(THREAD_CONTEXT threadContext);
-	
-};
-
-#endif /*FILEOUTPUT_H_*/

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/CMakeLists.txt b/artemis-native/src/main/c/CMakeLists.txt
index 0a45fd6..beef8da 100644
--- a/artemis-native/src/main/c/CMakeLists.txt
+++ b/artemis-native/src/main/c/CMakeLists.txt
@@ -30,35 +30,21 @@ endif()
 
 # you may want to remove this next line for debugging
 # -O3 would make inline debug hard
+#ADD_DEFINITIONS("-O3 -Wall -z execstack")
 ADD_DEFINITIONS("-O3 -Wall")
-#ADD_DEFINITIONS("-fdump-tree-all -Wall -pg -g -mstack-protector-guard=guard")
+#ADD_DEFINITIONS("-fdump-tree-all -Wall -pg -g")
 
 find_library(LIBAIO NAMES aio)
 
 INCLUDE_DIRECTORIES(. ${JNI_INCLUDE_DIRS})
 
 ADD_CUSTOM_COMMAND(
-    OUTPUT org_apache_activemq_artemis_core_libaio_Native.h
-    COMMAND javah -cp ../java/ org.apache.activemq.artemis.core.libaio.Native
-    DEPENDS ../java/org/apache/activemq/artemis/core/libaio/Native.java
+    OUTPUT org_apache_activemq_artemis_jlibaio_LibaioContext.h
+    COMMAND javah -cp ../java/ org.apache.activemq.artemis.jlibaio.LibaioContext
+    DEPENDS ../java/org/apache/activemq/artemis/jlibaio/LibaioContext.java
 )
 
-ADD_LIBRARY(artemis-native SHARED
-                AIOController.cpp
-                AIOController.h
-                AIOException.h
-                AsyncFile.cpp
-                AsyncFile.h
-                CallbackAdapter.h
-                JAIODatatypes.h
-                JavaUtilities.cpp
-                JavaUtilities.h
-                JNI_AsynchronousFileImpl.cpp
-                JNICallbackAdapter.cpp
-                JNICallbackAdapter.h
-                LockClass.h
-                Version.h
-                org_apache_activemq_artemis_core_libaio_Native.h)
+ADD_LIBRARY(artemis-native SHARED org_apache_activemq_artemis_jlibaio_LibaioContext.c org_apache_activemq_artemis_jlibaio_LibaioContext.h exception_helper.h)
 
 target_link_libraries(artemis-native aio)
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/CallbackAdapter.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/CallbackAdapter.h b/artemis-native/src/main/c/CallbackAdapter.h
deleted file mode 100644
index e8b67da..0000000
--- a/artemis-native/src/main/c/CallbackAdapter.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-  * 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.
-  */
-
-#ifndef BUFFERADAPTER_H_
-#define BUFFERADAPTER_H_
-
-#include <iostream>
-
-#include "JAIODatatypes.h"
-
-class CallbackAdapter
-{
-private:
-
-public:
-	CallbackAdapter()
-	{
-		
-	}
-	virtual ~CallbackAdapter()
-	{
-		
-	}
-	
-	virtual void done(THREAD_CONTEXT ) = 0;
-	virtual void onError(THREAD_CONTEXT , long , std::string )=0;
-};
-#endif /*BUFFERADAPTER_H_*/

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JAIODatatypes.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JAIODatatypes.h b/artemis-native/src/main/c/JAIODatatypes.h
deleted file mode 100644
index b611c2b..0000000
--- a/artemis-native/src/main/c/JAIODatatypes.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-  * 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.
-  */
-
-#ifndef JAIODATATYPES_H_
-#define JAIODATATYPES_H_
-
-#include <jni.h>
-
-#define THREAD_CONTEXT JNIEnv *&
-#define JNI_ENV(pointer) pointer 
-#define ALIGNMENT 512
-
-
-#endif /*JAIODATATYPES_H_*/

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JNICallbackAdapter.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JNICallbackAdapter.cpp b/artemis-native/src/main/c/JNICallbackAdapter.cpp
deleted file mode 100644
index 0f4cef4..0000000
--- a/artemis-native/src/main/c/JNICallbackAdapter.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-  * 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.
-  */
-
-#include <jni.h>
-#include "JNICallbackAdapter.h"
-#include <iostream>
-#include "JavaUtilities.h"
-
-jobject nullObj = NULL;
-
-JNICallbackAdapter::JNICallbackAdapter(AIOController * _controller, jlong _sequence, jobject _callback, jobject _fileController, jobject _bufferReference, short _isRead) : CallbackAdapter()
-{
-	controller = _controller;
-
-	sequence = _sequence;
-
-	callback = _callback;
-
-	fileController = _fileController;
-
-	bufferReference = _bufferReference;
-
-	isRead = _isRead;
-
-}
-
-JNICallbackAdapter::~JNICallbackAdapter()
-{
-}
-
-void JNICallbackAdapter::done(THREAD_CONTEXT threadContext)
-{
-	JNI_ENV(threadContext)->CallVoidMethod(fileController, controller->done, callback,  sequence, isRead ? nullObj : bufferReference); 
-
-	release(threadContext);
-}
-
-void JNICallbackAdapter::onError(THREAD_CONTEXT threadContext, long errorCode, std::string error)
-{
-	controller->log(threadContext, 0, "Libaio event generated errors, callback object was informed about it");
-
-	jstring strError = JNI_ENV(threadContext)->NewStringUTF(error.data());
-
-	JNI_ENV(threadContext)->CallVoidMethod(fileController, controller->error, callback, sequence, isRead ? nullObj : bufferReference, (jint)errorCode, strError);
-
-	release(threadContext);
-}
-

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JNICallbackAdapter.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JNICallbackAdapter.h b/artemis-native/src/main/c/JNICallbackAdapter.h
deleted file mode 100644
index 5d32620..0000000
--- a/artemis-native/src/main/c/JNICallbackAdapter.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-  * 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.
-  */
-
-#ifndef JNIBUFFERADAPTER_H_
-#define JNIBUFFERADAPTER_H_
-
-#include <iostream>
-
-#include "CallbackAdapter.h"
-#include "AIOController.h"
-#include "JAIODatatypes.h"
-
-
-class JNICallbackAdapter : public CallbackAdapter
-{
-private:
-
-	AIOController * controller;
-	
-	jobject callback;
-	
-	jobject fileController;
-	
-	jobject bufferReference;
-	
-	jlong sequence;
-	
-	// Is this a read operation
-	short isRead;
-
-	void release(THREAD_CONTEXT threadContext)
-	{
-		JNI_ENV(threadContext)->DeleteGlobalRef(callback);
-		JNI_ENV(threadContext)->DeleteGlobalRef(fileController);
-		JNI_ENV(threadContext)->DeleteGlobalRef(bufferReference);
-		delete this;
-		return;
-	}
-	
-	
-public:
-	// _ob must be a global Reference (use createGloblReferente before calling the constructor)
-	JNICallbackAdapter(AIOController * _controller, jlong sequence, jobject _callback, jobject _fileController, jobject _bufferReference, short _isRead);
-	virtual ~JNICallbackAdapter();
-
-	void done(THREAD_CONTEXT threadContext);
-
-	void onError(THREAD_CONTEXT , long , std::string );
-
-	
-};
-#endif /*JNIBUFFERADAPTER_H_*/

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JNI_AsynchronousFileImpl.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JNI_AsynchronousFileImpl.cpp b/artemis-native/src/main/c/JNI_AsynchronousFileImpl.cpp
deleted file mode 100644
index 0334a7c..0000000
--- a/artemis-native/src/main/c/JNI_AsynchronousFileImpl.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
-  * 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.
-  */
-
-#include <jni.h>
-#include <stdlib.h>
-#include <iostream>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string>
-#include <time.h>
-#include <sys/file.h>
-
-#include "org_apache_activemq_artemis_core_libaio_Native.h"
-
-
-#include "JavaUtilities.h"
-#include "AIOController.h"
-#include "JNICallbackAdapter.h"
-#include "AIOException.h"
-#include "Version.h"
-
-
-// This value is set here globally, to avoid passing stuff on stack between java and the native layer on every sleep call
-struct timespec nanoTime;
-
-inline AIOController * getController(JNIEnv *env, jobject & controllerAddress)
-{
-     return (AIOController *) env->GetDirectBufferAddress(controllerAddress);
-}
-
-/* Inaccessible static: log */
-/* Inaccessible static: totalMaxIO */
-/* Inaccessible static: loaded */
-/* Inaccessible static: EXPECTED_NATIVE_VERSION */
-/*
- * Class:     org.apache.activemq.artemis_core_asyncio_impl_AsynchronousFileImpl
- * Method:    openFile
- * Signature: (Ljava/lang/String;)I
- */
-JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_openFile
-  (JNIEnv * env , jclass , jstring jstrFileName)
-{
-	std::string fileName = convertJavaString(env, jstrFileName);
-
-    return open(fileName.data(), O_RDWR | O_CREAT, 0666);
-}
-
-/*
- * Class:     org.apache.activemq.artemis_core_asyncio_impl_AsynchronousFileImpl
- * Method:    closeFile
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_closeFile
-  (JNIEnv * , jclass , jint handle)
-{
-   close(handle);
-}
-
-/*
- * Class:     org.apache.activemq.artemis_core_asyncio_impl_AsynchronousFileImpl
- * Method:    flock
- * Signature: (I)Z
- */
-JNIEXPORT jboolean JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_flock
-  (JNIEnv * , jclass , jint handle)
-{
-    return flock(handle, LOCK_EX | LOCK_NB) == 0;
-}
-
-
-
-/*
- * Class:     org_jboss_jaio_libaioimpl_LibAIOController
- * Method:    init
- * Signature: (Ljava/lang/String;Ljava/lang/Class;)J
- */
-JNIEXPORT jobject JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_init
-  (JNIEnv * env, jclass, jclass controllerClazz, jstring jstrFileName, jint maxIO, jobject logger)
-{
-	AIOController * controller = 0;
-	try
-	{
-		std::string fileName = convertJavaString(env, jstrFileName);
-
-		controller = new AIOController(fileName, (int) maxIO);
-		controller->done = env->GetMethodID(controllerClazz,"callbackDone","(Lorg/apache/activemq/artemis/core/asyncio/AIOCallback;JLjava/nio/ByteBuffer;)V");
-		if (!controller->done)
-		{
-		   throwException (env, -1, "can't get callbackDone method");
-		   return 0;
-		}
-
-		controller->error = env->GetMethodID(controllerClazz, "callbackError", "(Lorg/apache/activemq/artemis/core/asyncio/AIOCallback;JLjava/nio/ByteBuffer;ILjava/lang/String;)V");
-		if (!controller->done)
-		{
-		   throwException (env, -1, "can't get callbackError method");
-		   return 0;
-		}
-
-        jclass loggerClass = env->GetObjectClass(logger);
-
-        if (!(controller->loggerDebug = env->GetMethodID(loggerClass, "debug", "(Ljava/lang/Object;)V"))) return 0;
-        if (!(controller->loggerWarn = env->GetMethodID(loggerClass, "warn", "(Ljava/lang/Object;)V"))) return 0;
-        if (!(controller->loggerInfo = env->GetMethodID(loggerClass, "info", "(Ljava/lang/Object;)V"))) return 0;
-        if (!(controller->loggerError = env->GetMethodID(loggerClass, "error", "(Ljava/lang/Object;)V"))) return 0;
-
-        controller->logger = env->NewGlobalRef(logger);
-
-		return env->NewDirectByteBuffer(controller, 0);
-	}
-	catch (AIOException& e){
-		if (controller != 0)
-		{
-			delete controller;
-		}
-		throwException(env, e.getErrorCode(), e.what());
-		return 0;
-	}
-}
-
-/**
-* objThis here is passed as a parameter at the java layer. It used to be a JNI this and now it's a java static method
-  where the intended reference is now passed as an argument
-*/
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_read
-  (JNIEnv *env, jclass, jobject objThis, jobject controllerAddress, jlong position, jlong size, jobject jbuffer, jobject callback)
-{
-	try
-	{
-		AIOController * controller = getController(env, controllerAddress);
-		void * buffer = env->GetDirectBufferAddress(jbuffer);
-
-		if (buffer == 0)
-		{
-			throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
-			return;
-		}
-
-		if (((long)buffer) % 512)
-		{
-			throwException(env, NATIVE_ERROR_NOT_ALIGNED, "Buffer not aligned for use with DMA");
-			return;
-		}
-
-		CallbackAdapter * adapter = new JNICallbackAdapter(controller, -1, env->NewGlobalRef(callback), env->NewGlobalRef(objThis), env->NewGlobalRef(jbuffer), true);
-
-		controller->fileOutput.read(env, position, (size_t)size, buffer, adapter);
-	}
-	catch (AIOException& e)
-	{
-		throwException(env, e.getErrorCode(), e.what());
-	}
-}
-
-
-// Fast memset on buffer
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_resetBuffer
-  (JNIEnv *env, jclass, jobject jbuffer, jint size)
-{
-	void * buffer = env->GetDirectBufferAddress(jbuffer);
-
-	if (buffer == 0)
-	{
-		throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
-		return;
-	}
-
-	memset(buffer, 0, (size_t)size);
-
-}
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_destroyBuffer
-  (JNIEnv * env, jclass, jobject jbuffer)
-{
-    if (jbuffer == 0)
-    {
-		throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Null Buffer");
-		return;
-    }
-	void *  buffer = env->GetDirectBufferAddress(jbuffer);
-	free(buffer);
-}
-
-JNIEXPORT jobject JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_newNativeBuffer
-  (JNIEnv * env, jclass, jlong size)
-{
-	try
-	{
-
-		if (size % ALIGNMENT)
-		{
-			throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Buffer size needs to be aligned to 512");
-			return 0;
-		}
-
-
-		// This will allocate a buffer, aligned by 512.
-		// Buffers created here need to be manually destroyed by destroyBuffer, or this would leak on the process heap away of Java's GC managed memory
-		void * buffer = 0;
-		if (::posix_memalign(&buffer, 512, size))
-		{
-			throwException(env, NATIVE_ERROR_INTERNAL, "Error on posix_memalign");
-			return 0;
-		}
-
-		memset(buffer, 0, (size_t)size);
-
-		jobject jbuffer = env->NewDirectByteBuffer(buffer, size);
-		return jbuffer;
-	}
-	catch (AIOException& e)
-	{
-		throwException(env, e.getErrorCode(), e.what());
-		return 0;
-	}
-}
-
-/**
-* objThis here is passed as a parameter at the java layer. It used to be a JNI this and now it's a java static method
-  where the intended reference is now passed as an argument
-*/
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_write
-  (JNIEnv *env, jclass, jobject objThis, jobject controllerAddress, jlong sequence, jlong position, jlong size, jobject jbuffer, jobject callback)
-{
-	try
-	{
-		AIOController * controller = getController(env, controllerAddress);
-		void * buffer = env->GetDirectBufferAddress(jbuffer);
-
-		if (buffer == 0)
-		{
-			throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
-			return;
-		}
-
-
-		CallbackAdapter * adapter = new JNICallbackAdapter(controller, sequence, env->NewGlobalRef(callback), env->NewGlobalRef(objThis), env->NewGlobalRef(jbuffer), false);
-
-		controller->fileOutput.write(env, position, (size_t)size, buffer, adapter);
-	}
-	catch (AIOException& e)
-	{
-		throwException(env, e.getErrorCode(), e.what());
-	}
-}
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_writeInternal
-  (JNIEnv * env, jclass, jobject controllerAddress, jlong positionToWrite, jlong size, jobject jbuffer)
-{
-	try
-	{
-		AIOController * controller = getController(env, controllerAddress);
-		void * buffer = env->GetDirectBufferAddress(jbuffer);
-
-		if (buffer == 0)
-		{
-			throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
-			return;
-		}
-
-		controller->fileOutput.writeInternal(env, positionToWrite, (size_t)size, buffer);
-	}
-	catch (AIOException& e)
-	{
-		throwException(env, e.getErrorCode(), e.what());
-	}
-}
-
-
-JNIEXPORT void Java_org_apache_activemq_artemis_core_libaio_Native_internalPollEvents
-  (JNIEnv *env, jclass, jobject controllerAddress)
-{
-	try
-	{
-		AIOController * controller = getController(env, controllerAddress);
-		controller->fileOutput.pollEvents(env);
-	}
-	catch (AIOException& e)
-	{
-		throwException(env, e.getErrorCode(), e.what());
-	}
-}
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_stopPoller
-  (JNIEnv *env, jclass, jobject controllerAddress)
-{
-	try
-	{
-		AIOController * controller = getController(env, controllerAddress);
-		controller->fileOutput.stopPoller(env);
-	}
-	catch (AIOException& e)
-	{
-		throwException(env, e.getErrorCode(), e.what());
-	}
-}
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_closeInternal
-  (JNIEnv *env, jclass, jobject controllerAddress)
-{
-	try
-	{
-		AIOController * controller = getController(env, controllerAddress);
-		controller->destroy(env);
-		delete controller;
-	}
-	catch (AIOException& e)
-	{
-		throwException(env, e.getErrorCode(), e.what());
-	}
-}
-
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_fill
-  (JNIEnv * env, jclass, jobject controllerAddress, jlong position, jint blocks, jlong size, jbyte fillChar)
-{
-	try
-	{
-		AIOController * controller = getController(env, controllerAddress);
-
-		controller->fileOutput.preAllocate(env, position, blocks, size, fillChar);
-
-	}
-	catch (AIOException& e)
-	{
-		throwException(env, e.getErrorCode(), e.what());
-	}
-}
-
-
-
-/** It does nothing... just return true to make sure it has all the binary dependencies */
-JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_getNativeVersion
-  (JNIEnv *, jclass)
-
-{
-     return _VERSION_NATIVE_AIO;
-}
-
-
-JNIEXPORT jlong JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_size0
-  (JNIEnv * env, jclass, jobject controllerAddress)
-{
-	try
-	{
-		AIOController * controller = getController(env, controllerAddress);
-
-		long size = controller->fileOutput.getSize();
-		if (size < 0)
-		{
-			throwException(env, NATIVE_ERROR_INTERNAL, "InternalError on Native Layer: method size failed");
-			return -1l;
-		}
-		return size;
-	}
-	catch (AIOException& e)
-	{
-		throwException(env, e.getErrorCode(), e.what());
-		return -1l;
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JavaUtilities.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JavaUtilities.cpp b/artemis-native/src/main/c/JavaUtilities.cpp
deleted file mode 100644
index 10d6099..0000000
--- a/artemis-native/src/main/c/JavaUtilities.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-  * 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.
-  */
-
-#include <stdio.h>
-#include <iostream>
-#include <string>
-#include "JavaUtilities.h"
-
-
-void throwRuntimeException(JNIEnv * env, const char * message)
-{
-  jclass exceptionClass = env->FindClass("java/lang/RuntimeException");
-  env->ThrowNew(exceptionClass,message);
-  
-}
-
-void throwException(JNIEnv * env, const int code, const char * message)
-{
-  jclass exceptionClass = env->FindClass("org/apache/activemq/artemis/api/core/ActiveMQException");
-  if (exceptionClass==NULL) 
-  {
-     std::cerr << "Couldn't throw exception message:= " << message << "\n";
-     throwRuntimeException (env, "Can't find Exception class");
-     return;
-  }
-
-  jmethodID constructor = env->GetMethodID(exceptionClass, "<init>", "(ILjava/lang/String;)V");
-  if (constructor == NULL)
-  {
-       std::cerr << "Couldn't find the constructor ***";
-       throwRuntimeException (env, "Can't find Constructor for Exception");
-       return;
-  }
-
-  jstring strError = env->NewStringUTF(message);
-  jthrowable ex = (jthrowable)env->NewObject(exceptionClass, constructor, code, strError);
-  env->Throw(ex);
-  
-}
-
-std::string convertJavaString(JNIEnv * env, jstring& jstr)
-{
-	const char * valueStr = env->GetStringUTFChars(jstr, NULL);
-	std::string data(valueStr);
-	env->ReleaseStringUTFChars(jstr, valueStr);
-	return data;
-}
-

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JavaUtilities.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JavaUtilities.h b/artemis-native/src/main/c/JavaUtilities.h
deleted file mode 100644
index 53ba870..0000000
--- a/artemis-native/src/main/c/JavaUtilities.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-  * 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.
-  */
-
-#ifndef JAVAUTILITIES_H_
-#define JAVAUTILITIES_H_
-#include <string>
-#include <jni.h>
-
-void throwException(JNIEnv * env, const int code, const char * message);
-std::string convertJavaString(JNIEnv * env, jstring& jstr);
-
-#endif /*JAVAUTILITIES_H_*/

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/LockClass.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/LockClass.h b/artemis-native/src/main/c/LockClass.h
deleted file mode 100644
index 5259919..0000000
--- a/artemis-native/src/main/c/LockClass.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-  * 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.
-  */
-
-#ifndef LOCKCLASS_H_
-#define LOCKCLASS_H_
-
-#include <pthread.h>
-
-class LockClass
-{
-protected:
-    pthread_mutex_t* _m;
-public:
-    inline LockClass(pthread_mutex_t* m) : _m(m)
-    {
-        ::pthread_mutex_lock(_m);
-    }
-    inline ~LockClass()
-    {
-        ::pthread_mutex_unlock(_m);
-    }
-};
-
-
-#endif /*LOCKCLASS_H_*/

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/Version.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/Version.h b/artemis-native/src/main/c/Version.h
deleted file mode 100644
index 5b521b3..0000000
--- a/artemis-native/src/main/c/Version.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-  * 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.
-  */
-
-#ifndef _VERSION_NATIVE_AIO
-
-// This definition needs to match org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl.EXPECTED_NATIVE_VERSION
-// Or else the native module won't be loaded because of version mismatches
-#define _VERSION_NATIVE_AIO 52
-#endif
-

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/exception_helper.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/exception_helper.h b/artemis-native/src/main/c/exception_helper.h
new file mode 100644
index 0000000..d8c7707
--- /dev/null
+++ b/artemis-native/src/main/c/exception_helper.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2015 The Netty Project
+ *
+ * The Netty Project 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.
+ */
+
+void throwRuntimeException(JNIEnv* env, char* message);
+void throwRuntimeExceptionErrorNo(JNIEnv* env, char* message, int errorNumber);
+void throwIOException(JNIEnv* env, char* message);
+void throwIOExceptionErrorNo(JNIEnv* env, char* message, int errorNumber);
+void throwClosedChannelException(JNIEnv* env);
+void throwOutOfMemoryError(JNIEnv* env);
+char* exceptionMessage(char* msg, int error);


[9/9] activemq-artemis git commit: merging #98 - ARTEMIS-163 Simplification of the native layer

Posted by an...@apache.org.
merging #98 - ARTEMIS-163 Simplification of the native layer


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/8182f8bd
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/8182f8bd
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/8182f8bd

Branch: refs/heads/master
Commit: 8182f8bd2d1b7d9165fd300d37b4dca75194acc5
Parents: 661f695 6fe9e0e
Author: Andy Taylor <an...@gmail.com>
Authored: Thu Jul 30 10:07:18 2015 +0100
Committer: Andy Taylor <an...@gmail.com>
Committed: Thu Jul 30 10:07:18 2015 +0100

----------------------------------------------------------------------
 .gitignore                                      |    2 +-
 CMakeLists.txt                                  |   18 +
 README.md                                       |    2 +-
 .../activemq/artemis/cli/commands/Create.java   |   90 +-
 .../cli/commands/tools/CompactJournal.java      |    6 +-
 .../cli/commands/tools/DecodeJournal.java       |    4 +-
 .../cli/commands/tools/EncodeJournal.java       |    6 +-
 .../cli/commands/tools/XmlDataExporter.java     |    6 +-
 .../cli/commands/util/SyncCalculation.java      |  190 ++++
 .../artemis/cli/commands/etc/broker.xml         |    1 +
 .../commands/etc/journal-buffer-settings.txt    |    8 +
 .../apache/activemq/cli/test/ArtemisTest.java   |   23 +-
 .../activemq/cli/test/StreamClassPathTest.java  |    1 +
 .../artemis/api/core/ActiveMQNativeIOError.java |    5 +
 .../journal/JMSJournalStorageManagerImpl.java   |    6 +-
 .../artemis/core/asyncio/AIOCallback.java       |   33 -
 .../artemis/core/asyncio/AsynchronousFile.java  |   58 -
 .../artemis/core/asyncio/BufferCallback.java    |   27 -
 .../core/asyncio/IOExceptionListener.java       |   22 -
 .../core/asyncio/impl/ActiveMQFileLock.java     |   47 -
 .../core/asyncio/impl/AsynchronousFileImpl.java |  822 --------------
 .../artemis/core/io/AbstractSequentialFile.java |  407 +++++++
 .../core/io/AbstractSequentialFileFactory.java  |  224 ++++
 .../activemq/artemis/core/io/DummyCallback.java |   49 +
 .../activemq/artemis/core/io/IOCallback.java    |   33 +
 .../core/io/IOCriticalErrorListener.java        |   25 +
 .../artemis/core/io/IOExceptionListener.java    |   22 +
 .../artemis/core/io/SequentialFile.java         |  116 ++
 .../artemis/core/io/SequentialFileFactory.java  |   91 ++
 .../artemis/core/io/aio/AIOSequentialFile.java  |  333 ++++++
 .../core/io/aio/AIOSequentialFileFactory.java   |  531 +++++++++
 .../artemis/core/io/aio/ActiveMQFileLock.java   |   47 +
 .../artemis/core/io/buffer/TimedBuffer.java     |  558 ++++++++++
 .../core/io/buffer/TimedBufferObserver.java     |   53 +
 .../artemis/core/io/nio/NIOSequentialFile.java  |  393 +++++++
 .../core/io/nio/NIOSequentialFileFactory.java   |  168 +++
 .../artemis/core/journal/IOAsyncTask.java       |   27 -
 .../artemis/core/journal/IOCompletion.java      |    4 +-
 .../core/journal/IOCriticalErrorListener.java   |   22 -
 .../activemq/artemis/core/journal/Journal.java  |    1 +
 .../artemis/core/journal/SequentialFile.java    |  129 ---
 .../core/journal/SequentialFileFactory.java     |   89 --
 .../core/journal/impl/AIOSequentialFile.java    |  326 ------
 .../journal/impl/AIOSequentialFileFactory.java  |  358 ------
 .../journal/impl/AbstractJournalUpdateTask.java |    8 +-
 .../journal/impl/AbstractSequentialFile.java    |  407 -------
 .../impl/AbstractSequentialFileFactory.java     |  218 ----
 .../core/journal/impl/DummyCallback.java        |   48 -
 .../core/journal/impl/FileWrapperJournal.java   |    2 +-
 .../artemis/core/journal/impl/JournalBase.java  |    1 +
 .../core/journal/impl/JournalCompactor.java     |    6 +-
 .../artemis/core/journal/impl/JournalFile.java  |    2 +-
 .../core/journal/impl/JournalFileImpl.java      |    2 +-
 .../journal/impl/JournalFilesRepository.java    |    8 +-
 .../artemis/core/journal/impl/JournalImpl.java  |   28 +-
 .../core/journal/impl/NIOSequentialFile.java    |  404 -------
 .../journal/impl/NIOSequentialFileFactory.java  |  168 ---
 .../core/journal/impl/SyncSpeedTest.java        |  354 ------
 .../artemis/core/journal/impl/TimedBuffer.java  |  558 ----------
 .../core/journal/impl/TimedBufferObserver.java  |   52 -
 .../core/journal/impl/TransactionCallback.java  |   12 +-
 .../artemis/core/io/aio/CallbackOrderTest.java  |   97 ++
 .../artemis/maven/ActiveMQCreatePlugin.java     |    1 +
 artemis-native/bin/libartemis-native-32.so      |  Bin 44082 -> 22260 bytes
 artemis-native/bin/libartemis-native-64.so      |  Bin 46624 -> 23984 bytes
 artemis-native/pom.xml                          |   24 +
 artemis-native/src/main/c/AIOController.cpp     |   63 --
 artemis-native/src/main/c/AIOController.h       |   51 -
 artemis-native/src/main/c/AIOException.h        |   75 --
 artemis-native/src/main/c/AsyncFile.cpp         |  348 ------
 artemis-native/src/main/c/AsyncFile.h           |   93 --
 artemis-native/src/main/c/CMakeLists.txt        |   26 +-
 artemis-native/src/main/c/CallbackAdapter.h     |   42 -
 artemis-native/src/main/c/JAIODatatypes.h       |   28 -
 .../src/main/c/JNICallbackAdapter.cpp           |   62 --
 artemis-native/src/main/c/JNICallbackAdapter.h  |   66 --
 .../src/main/c/JNI_AsynchronousFileImpl.cpp     |  377 -------
 artemis-native/src/main/c/JavaUtilities.cpp     |   62 --
 artemis-native/src/main/c/JavaUtilities.h       |   26 -
 artemis-native/src/main/c/LockClass.h           |   39 -
 artemis-native/src/main/c/Version.h             |   24 -
 artemis-native/src/main/c/exception_helper.h    |   23 +
 ...che_activemq_artemis_jlibaio_LibaioContext.c |  710 ++++++++++++
 .../activemq/artemis/core/libaio/Native.java    |   74 --
 .../activemq/artemis/jlibaio/LibaioContext.java |  446 ++++++++
 .../activemq/artemis/jlibaio/LibaioFile.java    |  152 +++
 .../activemq/artemis/jlibaio/NativeLogger.java  |   51 +
 .../activemq/artemis/jlibaio/SubmitInfo.java    |   25 +
 .../activemq/artemis/jlibaio/package-info.java  |   24 +
 .../artemis/jlibaio/util/CallbackCache.java     |   93 ++
 .../jlibaio/test/CallbackCachelTest.java        |  112 ++
 .../artemis/jlibaio/test/LibaioTest.java        |  859 +++++++++++++++
 .../plug/ProtonSessionIntegrationCallback.java  |    4 +-
 .../core/protocol/mqtt/MQTTPublishManager.java  |    4 +-
 .../openwire/OpenWireProtocolManager.java       |    4 +-
 .../protocol/stomp/StompProtocolManager.java    |    4 +-
 .../deployers/impl/FileConfigurationParser.java |    2 +-
 .../artemis/core/paging/PagingManager.java      |    2 +-
 .../artemis/core/paging/PagingStore.java        |    2 +-
 .../artemis/core/paging/PagingStoreFactory.java |    2 +-
 .../cursor/impl/PageSubscriptionImpl.java       |    6 +-
 .../activemq/artemis/core/paging/impl/Page.java |    4 +-
 .../core/paging/impl/PagingStoreFactoryNIO.java |    8 +-
 .../core/paging/impl/PagingStoreImpl.java       |   10 +-
 .../core/persistence/OperationContext.java      |    4 +-
 .../core/persistence/StorageManager.java        |    6 +-
 .../impl/journal/DescribeJournal.java           |    8 +-
 .../impl/journal/JournalStorageManager.java     |   33 +-
 .../impl/journal/LargeServerMessageImpl.java    |    2 +-
 .../impl/journal/LargeServerMessageInSync.java  |    4 +-
 .../impl/journal/OperationContextImpl.java      |   12 +-
 .../nullpm/NullStorageLargeServerMessage.java   |    2 +-
 .../impl/nullpm/NullStorageManager.java         |    8 +-
 .../core/postoffice/impl/PostOfficeImpl.java    |    6 +-
 .../core/ServerSessionPacketHandler.java        |    4 +-
 .../core/replication/ReplicatedJournal.java     |    2 +-
 .../core/replication/ReplicationEndpoint.java   |    6 +-
 .../core/replication/ReplicationManager.java    |    2 +-
 .../core/server/ActiveMQServerLogger.java       |   10 +-
 .../artemis/core/server/LargeServerMessage.java |    2 +-
 .../core/server/cluster/impl/Redistributor.java |    4 +-
 .../server/impl/AIOFileLockNodeManager.java     |   29 +-
 .../core/server/impl/ActiveMQServerImpl.java    |   18 +-
 .../artemis/core/server/impl/QueueImpl.java     |    4 +-
 .../core/server/impl/ServerSessionImpl.java     |    4 +-
 .../core/transaction/impl/TransactionImpl.java  |    8 +-
 .../artemis/tests/util/ActiveMQTestBase.java    |   66 +-
 .../tests/util/ColocatedActiveMQServer.java     |    7 +-
 .../integration/client/HangConsumerTest.java    |    6 +-
 .../integration/client/JournalCrashTest.java    |    4 +-
 .../client/LibaioDependencyCheckTest.java       |    4 +-
 .../tests/integration/client/PagingTest.java    |    8 +-
 .../client/RedeliveryConsumerTest.java          |    4 +-
 .../integration/cluster/bridge/BridgeTest.java  |    6 +-
 .../journal/AIOImportExportTest.java            |    6 +-
 .../journal/AIOJournalCompactTest.java          |    6 +-
 .../integration/journal/AIOJournalImplTest.java |   10 +-
 .../journal/AIOSequentialFileFactoryTest.java   |   10 +-
 .../journal/NIOBufferedJournalCompactTest.java  |    6 +-
 .../journal/NIOImportExportTest.java            |    6 +-
 .../journal/NIOJournalCompactTest.java          |   16 +-
 .../integration/journal/NIOJournalImplTest.java |    6 +-
 .../journal/NIONoBufferJournalImplTest.java     |    6 +-
 ...NIONonBufferedSequentialFileFactoryTest.java |    6 +-
 .../journal/NIOSequentialFileFactoryTest.java   |    6 +-
 .../journal/ValidateTransactionHealthTest.java  |   15 +-
 .../management/ActiveMQServerControlTest.java   |   12 +-
 .../replication/ReplicationTest.java            |   16 +-
 .../integration/server/FileLockTimeoutTest.java |    4 +-
 .../journal/FakeJournalImplTest.java            |    2 +-
 .../journal/JournalImplTestUnit.java            |   13 +-
 .../journal/RealJournalImplAIOTest.java         |    6 +-
 .../journal/RealJournalImplNIOTest.java         |    6 +-
 .../AIOAllPossibilitiesCompactStressTest.java   |    6 +-
 .../AIOMultiThreadCompactorStressTest.java      |    2 +-
 .../stress/journal/AddAndRemoveStressTest.java  |   16 +-
 .../stress/journal/CompactingStressTest.java    |   12 +-
 .../JournalCleanupCompactStressTest.java        |   50 +-
 .../stress/journal/MixupCompactorTestBase.java  |    6 +-
 .../NIOMultiThreadCompactorStressTest.java      |    8 +-
 .../core/journal/impl/AIOJournalImplTest.java   |    6 +-
 .../core/journal/impl/FakeJournalImplTest.java  |    2 +-
 .../core/journal/impl/JournalImplTestUnit.java  |   15 +-
 .../core/journal/impl/NIOJournalImplTest.java   |    6 +-
 .../tests/unit/core/asyncio/AIOTestBase.java    |   18 +-
 .../unit/core/asyncio/AsynchronousFileTest.java | 1015 ------------------
 .../MultiThreadAsynchronousFileTest.java        |   81 +-
 .../journal/impl/AlignedJournalImplTest.java    |   14 +-
 .../unit/core/journal/impl/CleanBufferTest.java |   16 +-
 .../core/journal/impl/FakeJournalImplTest.java  |    2 +-
 .../impl/FakeSequentialFileFactoryTest.java     |    2 +-
 .../core/journal/impl/FileFactoryTestBase.java  |   18 +-
 .../core/journal/impl/JournalImplTestBase.java  |    6 +-
 .../core/journal/impl/JournalImplTestUnit.java  |    9 +-
 .../unit/core/journal/impl/ReclaimerTest.java   |    2 +-
 .../impl/SequentialFileFactoryTestBase.java     |   52 +-
 .../unit/core/journal/impl/TimedBufferTest.java |   26 +-
 .../impl/fakes/FakeSequentialFileFactory.java   |   84 +-
 .../tests/unit/core/paging/impl/PageTest.java   |   18 +-
 .../core/paging/impl/PagingStoreImplTest.java   |   14 +-
 .../impl/BatchIDGeneratorUnitTest.java          |    4 +-
 .../impl/OperationContextUnitTest.java          |    8 +-
 .../unit/core/server/impl/FileLockTest.java     |    4 +-
 183 files changed, 6522 insertions(+), 7227 deletions(-)
----------------------------------------------------------------------