diff --git a/ttorrent-client/src/main/java/com/turn/ttorrent/client/SharedTorrent.java b/ttorrent-client/src/main/java/com/turn/ttorrent/client/SharedTorrent.java index 57e5e2ba2..3f6309850 100644 --- a/ttorrent-client/src/main/java/com/turn/ttorrent/client/SharedTorrent.java +++ b/ttorrent-client/src/main/java/com/turn/ttorrent/client/SharedTorrent.java @@ -270,7 +270,7 @@ private void hashSingleThread() { public synchronized void close() { logger.trace("Closing torrent", myTorrentMetadata.getDirectoryName()); try { - this.pieceStorage.close(); + this.pieceStorage.closeFully(); isFileChannelOpen = false; } catch (IOException ioe) { logger.error("Error closing torrent byte storage: {}", diff --git a/ttorrent-client/src/main/java/com/turn/ttorrent/client/storage/PieceStorage.java b/ttorrent-client/src/main/java/com/turn/ttorrent/client/storage/PieceStorage.java index 684213b93..66318fd39 100644 --- a/ttorrent-client/src/main/java/com/turn/ttorrent/client/storage/PieceStorage.java +++ b/ttorrent-client/src/main/java/com/turn/ttorrent/client/storage/PieceStorage.java @@ -14,4 +14,6 @@ public interface PieceStorage extends Closeable { boolean isFinished(); + void closeFully() throws IOException; + } diff --git a/ttorrent-client/src/main/java/com/turn/ttorrent/client/storage/PieceStorageImpl.java b/ttorrent-client/src/main/java/com/turn/ttorrent/client/storage/PieceStorageImpl.java index af3a6f4f0..189d74920 100644 --- a/ttorrent-client/src/main/java/com/turn/ttorrent/client/storage/PieceStorageImpl.java +++ b/ttorrent-client/src/main/java/com/turn/ttorrent/client/storage/PieceStorageImpl.java @@ -20,6 +20,7 @@ public class PieceStorageImpl implements PieceStorage { private final int piecesCount; private final int pieceSize; private volatile boolean isOpen; + private volatile boolean closedFully = false; public PieceStorageImpl(TorrentByteStorage fileCollectionStorage, BitSet availablePieces, @@ -49,6 +50,8 @@ public void savePiece(int pieceIndex, byte[] pieceData) throws IOException { try { readWriteLock.writeLock().lock(); + if (closedFully) throw new IOException("Storage is closed"); + BitSet availablePieces = this.availablePieces; boolean isFullyDownloaded = availablePieces == null; @@ -90,6 +93,8 @@ public byte[] readPiecePart(int pieceIndex, int offset, int length) throws IOExc try { readWriteLock.readLock().lock(); + if (closedFully) throw new IOException("Storage is closed"); + BitSet availablePieces = this.availablePieces; if (availablePieces != null && !availablePieces.get(pieceIndex)) { throw new IllegalArgumentException("trying reading part of not available piece"); @@ -119,6 +124,17 @@ public boolean isFinished() { } } + @Override + public void closeFully() throws IOException { + try { + readWriteLock.writeLock().lock(); + close0(); + closedFully = true; + } finally { + readWriteLock.writeLock().unlock(); + } + } + @Override public BitSet getAvailablePieces() { try { @@ -143,11 +159,15 @@ public BitSet getAvailablePieces() { public void close() throws IOException { try { readWriteLock.writeLock().lock(); - if (!isOpen) return; - fileCollectionStorage.close(); - isOpen = false; + close0(); } finally { readWriteLock.writeLock().unlock(); } } + + private void close0() throws IOException { + if (!isOpen) return; + fileCollectionStorage.close(); + isOpen = false; + } }