close the file before marking pieces complete

pull/5/head
Zlatin Balevsky 2019-06-16 23:45:23 +01:00
parent 4d001ae74b
commit b507361c58
1 changed files with 35 additions and 31 deletions

View File

@ -66,6 +66,8 @@ class DownloadSession {
int piece int piece
while(true) { while(true) {
piece = downloaded.getRandomPiece() piece = downloaded.getRandomPiece()
if (piece == -1)
return false
if (claimed.isMarked(piece)) { if (claimed.isMarked(piece)) {
if (downloaded.donePieces() + claimed.donePieces() == downloaded.nPieces) { if (downloaded.donePieces() + claimed.donePieces() == downloaded.nPieces) {
log.info("all pieces claimed") log.info("all pieces claimed")
@ -85,7 +87,6 @@ class DownloadSession {
String root = Base64.encode(infoHash.getRoot()) String root = Base64.encode(infoHash.getRoot())
FileChannel channel
try { try {
os.write("GET $root\r\n".getBytes(StandardCharsets.US_ASCII)) os.write("GET $root\r\n".getBytes(StandardCharsets.US_ASCII))
os.write("Range: $start-$end\r\n".getBytes(StandardCharsets.US_ASCII)) os.write("Range: $start-$end\r\n".getBytes(StandardCharsets.US_ASCII))
@ -135,41 +136,44 @@ class DownloadSession {
} }
// start the download // start the download
channel = Files.newByteChannel(file.toPath(), EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, FileChannel channel
StandardOpenOption.SPARSE, StandardOpenOption.CREATE)) // TODO: double-check, maybe CREATE_NEW try {
mapped = channel.map(FileChannel.MapMode.READ_WRITE, start, end - start + 1) channel = Files.newByteChannel(file.toPath(), EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE,
StandardOpenOption.SPARSE, StandardOpenOption.CREATE)) // TODO: double-check, maybe CREATE_NEW
byte[] tmp = new byte[0x1 << 13] mapped = channel.map(FileChannel.MapMode.READ_WRITE, start, end - start + 1)
while(mapped.hasRemaining()) {
if (mapped.remaining() < tmp.length) byte[] tmp = new byte[0x1 << 13]
tmp = new byte[mapped.remaining()] while(mapped.hasRemaining()) {
int read = is.read(tmp) if (mapped.remaining() < tmp.length)
if (read == -1) tmp = new byte[mapped.remaining()]
throw new IOException() int read = is.read(tmp)
synchronized(this) { if (read == -1)
mapped.put(tmp, 0, read) throw new IOException()
synchronized(this) {
if (timestamps.size() == SAMPLES) { mapped.put(tmp, 0, read)
timestamps.removeFirst()
reads.removeFirst() if (timestamps.size() == SAMPLES) {
timestamps.removeFirst()
reads.removeFirst()
}
timestamps.addLast(System.currentTimeMillis())
reads.addLast(read)
} }
timestamps.addLast(System.currentTimeMillis())
reads.addLast(read)
} }
mapped.clear()
digest.update(mapped)
byte [] hash = digest.digest()
byte [] expected = new byte[32]
System.arraycopy(infoHash.getHashList(), piece * 32, expected, 0, 32)
if (hash != expected)
throw new BadHashException()
} finally {
try { channel?.close() } catch (IOException ignore) {}
} }
downloaded.markDownloaded(piece)
mapped.clear()
digest.update(mapped)
byte [] hash = digest.digest()
byte [] expected = new byte[32]
System.arraycopy(infoHash.getHashList(), piece * 32, expected, 0, 32)
if (hash != expected)
throw new BadHashException()
downloaded.markDownloaded(piece)
} finally { } finally {
claimed.clear(piece) claimed.clear(piece)
try { channel?.close() } catch (IOException ignore) {}
} }
return true return true
} }