From a7a3d5ab98ee0ad33fdef50bf081afeb8295ebe4 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 3 Oct 2014 03:12:42 +0200 Subject: MappedByteBuffer*Stream: - Validate active and GC'ed mapped-buffer count in cleanAllSlices() via close() .. - Fix missing unmapping last buffer in notifyLengthChangeImpl(), branch criteria was off by one. - cleanSlice(..) now also issues cleanBuffer(..) on the GC'ed entry, hence if WeakReference is still alive, enforce it's release. - cleanBuffer(..) reverts FLUSH_PRE_HARD -> FLUSH_PRE_SOFT in case of an error. - flush() -> flush(boolean metaData) to expose FileChannel.force(metaData). - Add synchronous mode, flushing/syncing the mapped buffers when in READ_WRITE mapping mode and issue FileChannel.force() if not READ_ONLY. Above is implemented via flush()/flushImpl(..) for buffers and FileChannel, as well as in syncSlice(..) for buffers only. flush*()/syncSlice() is covered by: - setLength() - notifyLengthChange*(..) - nextSlice() Always issue flushImpl() in close(). - Windows: Clean all buffers in setLength(), otherwise Windows will report: - Windows: Catch MappedByteBuffer.force() IOException - Optimization of position(..) position(..) is now standalone to allow issuing flushSlice(..) before gathering the new mapped buffer. This shall avoid one extra cache miss. Hence rename positionImpl(..) -> position2(..). - All MappedByteBufferOutputStream.write(..) methods issue syncSlice(..) on the last written current slice to ensure new 'synchronous' mode is honored. +++ Unit tests: - Ensure test files are being deleted - TestByteBufferCopyStream: Reduced test file size to more sensible values. - --- .../common/nio/MappedByteBufferOutputStream.java | 49 ++++++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'src/java/com/jogamp/common/nio/MappedByteBufferOutputStream.java') diff --git a/src/java/com/jogamp/common/nio/MappedByteBufferOutputStream.java b/src/java/com/jogamp/common/nio/MappedByteBufferOutputStream.java index f84e6c2..8adf0e4 100644 --- a/src/java/com/jogamp/common/nio/MappedByteBufferOutputStream.java +++ b/src/java/com/jogamp/common/nio/MappedByteBufferOutputStream.java @@ -78,6 +78,19 @@ public class MappedByteBufferOutputStream extends OutputStream { this(new MappedByteBufferInputStream(fileChannel, mmode, cmode, sliceShift, fileChannel.size(), 0), fileResizeOp); } + /** + * See {@link MappedByteBufferInputStream#setSynchronous(boolean)}. + */ + public final synchronized void setSynchronous(final boolean s) { + parent.setSynchronous(s); + } + /** + * See {@link MappedByteBufferInputStream#getSynchronous()}. + */ + public final synchronized boolean getSynchronous() { + return parent.getSynchronous(); + } + /** * See {@link MappedByteBufferInputStream#setLength(long)}. */ @@ -129,7 +142,15 @@ public class MappedByteBufferOutputStream extends OutputStream { @Override public final synchronized void flush() throws IOException { - parent.flush(); + parent.flush( true /* metaData */); + } + + /** + * See {@link MappedByteBufferInputStream#flush(boolean)}. + */ + // @Override + public final synchronized void flush(final boolean metaData) throws IOException { + parent.flush(metaData); } @Override @@ -156,6 +177,11 @@ public class MappedByteBufferOutputStream extends OutputStream { } } slice.put( (byte)(b & 0xFF) ); + + // sync last buffer (happens only in synchronous mode) + if( null != slice ) { + parent.syncSlice(slice); + } } @Override @@ -178,8 +204,9 @@ public class MappedByteBufferOutputStream extends OutputStream { parent.setLength( parent.length() + len - totalRem ); } int written = 0; + ByteBuffer slice = null; while( written < len ) { - ByteBuffer slice = parent.currentSlice(); + slice = parent.currentSlice(); int currRem = slice.remaining(); if ( 0 == currRem ) { if ( null == ( slice = parent.nextSlice() ) ) { @@ -197,6 +224,10 @@ public class MappedByteBufferOutputStream extends OutputStream { slice.put( b, off + written, currLen ); written += currLen; } + // sync last buffer (happens only in synchronous mode) + if( null != slice ) { + parent.syncSlice(slice); + } } /** @@ -221,8 +252,9 @@ public class MappedByteBufferOutputStream extends OutputStream { parent.setLength( parent.length() + len - totalRem ); } int written = 0; + ByteBuffer slice = null; while( written < len ) { - ByteBuffer slice = parent.currentSlice(); + slice = parent.currentSlice(); int currRem = slice.remaining(); if ( 0 == currRem ) { if ( null == ( slice = parent.nextSlice() ) ) { @@ -257,6 +289,10 @@ public class MappedByteBufferOutputStream extends OutputStream { } written += currLen; } + // sync last buffer (happens only in synchronous mode) + if( null != slice ) { + parent.syncSlice(slice); + } } /** @@ -285,8 +321,9 @@ public class MappedByteBufferOutputStream extends OutputStream { parent.setLength( parent.length() + len - totalRem ); } long written = 0; + ByteBuffer slice = null; while( written < len ) { - ByteBuffer slice = parent.currentSlice(); + slice = parent.currentSlice(); int currRem = slice.remaining(); if ( 0 == currRem ) { if ( null == ( slice = parent.nextSlice() ) ) { @@ -306,5 +343,9 @@ public class MappedByteBufferOutputStream extends OutputStream { } written += currLen; } + // sync last buffer (happens only in synchronous mode) + if( null != slice ) { + parent.syncSlice(slice); + } } } -- cgit v1.2.3