{
return cp->completeBlocks[piece] == tr_torPieceCountBlocks( cp->tor, piece );
}
+
+tr_bool
+tr_cpFileIsComplete( const tr_completion * cp, tr_file_index_t fileIndex )
+{
+ tr_block_index_t block;
+
+ const tr_torrent * tor = cp->tor;
+ const tr_file * file = &tor->info.files[fileIndex];
+ const tr_block_index_t firstBlock = file->offset / tor->blockSize;
+ const tr_block_index_t lastBlock = ( file->offset + file->length - 1 ) / tor->blockSize;
+
+ assert( tr_torBlockPiece( tor, firstBlock ) == file->firstPiece );
+ assert( tr_torBlockPiece( tor, lastBlock ) == file->lastPiece );
+
+ for( block=firstBlock; block<=lastBlock; ++block )
+ if( !tr_cpBlockIsComplete( cp, block ) )
+ return FALSE;
+
+ return TRUE;
+}
void tr_cpPieceRem( tr_completion * completion,
tr_piece_index_t piece );
+tr_bool tr_cpFileIsComplete( const tr_completion * cp, tr_file_index_t );
+
/**
*** Blocks
**/
-static TR_INLINE int tr_cpBlockIsComplete( const tr_completion * cp, tr_block_index_t block ) {
+static TR_INLINE tr_bool tr_cpBlockIsComplete( const tr_completion * cp, tr_block_index_t block ) {
return tr_bitfieldHas( &cp->blockBitfield, block );
}
#include "clients.h"
#include "completion.h"
#include "crypto.h"
+#include "fdlimit.h"
#include "handshake.h"
#include "inout.h" /* tr_ioTestPiece */
#include "net.h"
case TR_PEER_CLIENT_GOT_BLOCK:
{
- tr_torrent * tor = t->tor;
+ tr_torrent * tor = t->tor;
tr_block_index_t block = _tr_block( tor, e->pieceIndex, e->offset );
tr_peerMgrSetBlame( tor->session->peerMgr, tor->info.hash, p, ok );
if( !ok )
+ {
gotBadPiece( t, p );
+ }
else
{
int i;
- int peerCount = tr_ptrArraySize( &t->peers );
- tr_peer ** peers = (tr_peer**) tr_ptrArrayBase( &t->peers );
+ int peerCount;
+ tr_peer ** peers;
+ tr_file_index_t fileIndex;
+
+ peerCount = tr_ptrArraySize( &t->peers );
+ peers = (tr_peer**) tr_ptrArrayBase( &t->peers );
for( i=0; i<peerCount; ++i )
tr_peerMsgsHave( peers[i]->msgs, p );
+
+ for( fileIndex=0; fileIndex<tor->info.fileCount; ++fileIndex )
+ {
+ const tr_file * file = &tor->info.files[fileIndex];
+ if( ( file->firstPiece <= p ) && ( p <= file->lastPiece ) && tr_cpFileIsComplete( &tor->completion, fileIndex ) )
+ {
+ char * path = tr_buildPath( tor->downloadDir, file->name, NULL );
+ tordbg( t, "closing recently-completed file \"%s\"", path );
+ tr_fdFileClose( path );
+ tr_free( path );
+ }
+ }
}
tr_torrentRecheckCompleteness( tor );