From a65d3f2581a2cf3b9b05c243a5d40ca31bd7aaa0 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 10 Aug 2016 19:03:23 +0200 Subject: Fix: Some chunks could be dropped from the hash queue and not marked as to-be-hashed again --- .../java/org/openslx/filetransfer/util/ChunkList.java | 11 +++++++++++ .../java/org/openslx/filetransfer/util/FileChunk.java | 4 ++-- .../java/org/openslx/filetransfer/util/HashChecker.java | 1 + .../openslx/filetransfer/util/IncomingTransferBase.java | 15 ++++++++++++--- 4 files changed, 26 insertions(+), 5 deletions(-) (limited to 'src/main/java/org/openslx/filetransfer/util') diff --git a/src/main/java/org/openslx/filetransfer/util/ChunkList.java b/src/main/java/org/openslx/filetransfer/util/ChunkList.java index c497be0..c692499 100644 --- a/src/main/java/org/openslx/filetransfer/util/ChunkList.java +++ b/src/main/java/org/openslx/filetransfer/util/ChunkList.java @@ -309,6 +309,17 @@ public class ChunkList return allChunks; } + public synchronized String getQueueName( FileChunk chunk ) + { + if ( missingChunks.contains( chunk ) ) + return "missing"; + if ( pendingChunks.contains( chunk ) ) + return "pending"; + if ( completeChunks.contains( chunk ) ) + return "completed"; + return "NOQUEUE"; + } + public static boolean hashListsEqualFcBb( List one, List two ) { return hashListsEqualFcArray( one, ThriftUtil.unwrapByteBufferList( two ) ); diff --git a/src/main/java/org/openslx/filetransfer/util/FileChunk.java b/src/main/java/org/openslx/filetransfer/util/FileChunk.java index 0aff296..e00b011 100644 --- a/src/main/java/org/openslx/filetransfer/util/FileChunk.java +++ b/src/main/java/org/openslx/filetransfer/util/FileChunk.java @@ -7,7 +7,7 @@ import org.openslx.filetransfer.FileRange; public class FileChunk { - + /** * Length in bytes of binary sha1 representation */ @@ -60,7 +60,7 @@ public class FileChunk @Override public String toString() { - return "[Chunk " + getChunkIndex() + " (" + range.startOffset + "-" + range.endOffset + "), fails: " + failCount + "]"; + return "[Chunk " + getChunkIndex() + " (" + status + "), fails: " + failCount + "]"; } public synchronized byte[] getSha1Sum() diff --git a/src/main/java/org/openslx/filetransfer/util/HashChecker.java b/src/main/java/org/openslx/filetransfer/util/HashChecker.java index 5fdf582..b9b62b1 100644 --- a/src/main/java/org/openslx/filetransfer/util/HashChecker.java +++ b/src/main/java/org/openslx/filetransfer/util/HashChecker.java @@ -39,6 +39,7 @@ public class HashChecker private void threadFailed( CheckThread thread ) { synchronized ( threads ) { + threads.remove( thread ); if ( thread.extraThread ) return; invalid = true; diff --git a/src/main/java/org/openslx/filetransfer/util/IncomingTransferBase.java b/src/main/java/org/openslx/filetransfer/util/IncomingTransferBase.java index 518a29f..92c26c9 100644 --- a/src/main/java/org/openslx/filetransfer/util/IncomingTransferBase.java +++ b/src/main/java/org/openslx/filetransfer/util/IncomingTransferBase.java @@ -289,6 +289,8 @@ public abstract class IncomingTransferBase extends AbstractTransfer implements H try { hashChecker.queue( currentChunk, buffer, IncomingTransferBase.this, true ); } catch ( InterruptedException e ) { + chunks.markCompleted( currentChunk, false ); + currentChunk = null; Thread.currentThread().interrupt(); return null; } @@ -317,9 +319,10 @@ public abstract class IncomingTransferBase extends AbstractTransfer implements H } else { // We have no hash checker or the hash for the current chunk is unknown - flush to disk writeFileData( currentChunk.range.startOffset, currentChunk.range.getLength(), buffer ); - chunks.markCompleted( currentChunk, true ); + chunks.markCompleted( currentChunk, false ); chunkStatusChanged( currentChunk ); } + currentChunk = null; } // Get next missing chunk try { @@ -445,8 +448,10 @@ public abstract class IncomingTransferBase extends AbstractTransfer implements H @Override public void hashCheckDone( HashResult result, byte[] data, FileChunk chunk ) { - if ( state != TransferState.IDLE && state != TransferState.WORKING ) + if ( state != TransferState.IDLE && state != TransferState.WORKING ) { + LOGGER.debug( "hashCheckDone called in bad state " + state.name() ); return; + } switch ( result ) { case FAILURE: LOGGER.warn( "Hash check of chunk " + chunk.toString() @@ -497,8 +502,12 @@ public abstract class IncomingTransferBase extends AbstractTransfer implements H return; } try { - hashChecker.queue( chunk, data, this, blocking ); + if ( !hashChecker.queue( chunk, data, this, blocking ) ) { + chunks.markCompleted( chunk, false ); + } } catch ( InterruptedException e ) { + LOGGER.debug( "Interrupted while trying to queueUnhashedChunk" ); + chunks.markCompleted( chunk, false ); Thread.currentThread().interrupt(); } } -- cgit v1.2.3-55-g7522