* 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 */
public void testConcurrentClose() throws Exception
{
final AsynchronousFileImpl controller = new AsynchronousFileImpl(executor, pollerExecutor);
try
{
final int NUMBER_LINES = 1000;
CountDownLatch readLatch = new CountDownLatch(NUMBER_LINES);
final int SIZE = 1024;
controller.open(FILE_NAME, 10000);
controller.fill(0, 1, NUMBER_LINES * SIZE, (byte)'j');
controller.setBufferCallback(new BufferCallback()
{
public void bufferDone(final ByteBuffer buffer)
{
AsynchronousFileImpl.destroyBuffer(buffer);
}
});
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);
Assert.assertEquals(0, readLatch.getCount());
readLatch.await();
controller.open(FILE_NAME, 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);
latch.await();
Assert.assertEquals(0, aio.errorCalled);
Assert.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++)
{
Assert.assertEquals("byte position " + count + " differs on line " + i,
bytesCompare[count],
bytesRead[count]);
}
Assert.assertTrue(buffer.equals(newBuffer));
}
AsynchronousFileImpl.destroyBuffer(newBuffer);
AsynchronousFileImpl.destroyBuffer(buffer);
}
finally
{
try
{
controller.close();
}
catch (Throwable ignored)
{
}