fix endgame bugs

This commit is contained in:
Charles Kerr
2007-07-06 16:17:37 +00:00
parent 3fda85725c
commit a166914a27
3 changed files with 39 additions and 27 deletions
+24 -5
View File
@@ -154,6 +154,9 @@ struct tr_peer_s
/* The pieces that the peer has */
tr_bitfield_t * bitfield;
/* blocks we've requested from this peer */
tr_bitfield_t * reqfield;
int pieceCount;
float progress;
@@ -231,10 +234,19 @@ static void __peer_dbg( tr_peer_t * peer, char * msg, ... )
**********************************************************************/
tr_peer_t * tr_peerInit( struct in_addr addr, in_port_t port, int s, int from )
{
tr_peer_t * peer = peerInit();
tr_peer_t * peer;
assert( 0 <= from && TR_PEER_FROM__MAX > from );
peer = tr_new0( tr_peer_t, 1 );
peertreeInit( &peer->sentPeers );
peer->amChoking = TRUE;
peer->peerChoking = TRUE;
peer->date = tr_date();
peer->keepAlive = peer->date;
peer->download = tr_rcInit();
peer->upload = tr_rcInit();
peer->outRequestMax = peer->outRequestAlloc = 2;
peer->outRequests = tr_new0( tr_request_t, peer->outRequestAlloc );
@@ -275,6 +287,7 @@ void tr_peerDestroy( tr_peer_t * peer )
tr_bitfieldFree( peer->bitfield );
tr_bitfieldFree( peer->blamefield );
tr_bitfieldFree( peer->banfield );
tr_bitfieldFree( peer->reqfield );
tr_free( peer->inRequests );
tr_free( peer->outRequests );
tr_free( peer->buf );
@@ -621,10 +634,16 @@ writeEnd:
if( endgame ) /* endgame -- request everything we don't already have */
{
const tr_bitfield_t * blocks = tr_cpBlockBitfield( tor->completion );
for( i=0; i<tor->blockCount && peer->inRequestCount<peer->inRequestMax; ++i ) {
if( tr_bitfieldHas( blocks, i ) )
sendRequest( tor, peer, i );
for( i=0; i<tor->blockCount && peer->inRequestCount<peer->inRequestMax; ++i )
{
if( !isBlockInteresting( tor, peer, i ) )
continue;
if( tr_bitfieldHas( peer->reqfield, i ) ) /* we've already asked them for it */
continue;
if( !peer->reqfield )
peer->reqfield = tr_bitfieldNew( tor->blockCount );
tr_bitfieldAdd( peer->reqfield, i );
sendRequest( tor, peer, i );
}
}
else for( i=0; i<poolSize && peer->inRequestCount<peer->inRequestMax; )
+14 -21
View File
@@ -24,26 +24,6 @@
static void updateInterest( tr_torrent_t * tor, tr_peer_t * peer );
/***********************************************************************
* peerInit
***********************************************************************
* Allocates a new tr_peer_t and returns a pointer to it.
**********************************************************************/
static tr_peer_t * peerInit()
{
tr_peer_t * peer;
peer = calloc( sizeof( tr_peer_t ), 1 );
peertreeInit( &peer->sentPeers );
peer->amChoking = 1;
peer->peerChoking = 1;
peer->date = tr_date();
peer->keepAlive = peer->date;
peer->download = tr_rcInit();
peer->upload = tr_rcInit();
return peer;
}
static int peerCmp( tr_peer_t * peer1, tr_peer_t * peer2 )
{
@@ -189,6 +169,9 @@ static int isPieceInteresting( const tr_torrent_t * tor,
const tr_peer_t * peer,
int piece )
{
if( tr_cpPieceIsComplete( tor->completion, piece ) ) /* we already have it */
return 0;
if( tor->info.pieces[piece].priority == TR_PRI_DND ) /* we don't want it */
return 0;
@@ -198,7 +181,17 @@ static int isPieceInteresting( const tr_torrent_t * tor,
if( tr_bitfieldHas( peer->banfield, piece ) ) /* peer is banned for it */
return 0;
if( tr_cpPieceIsComplete( tor->completion, piece ) ) /* we already have it */
return 1;
}
static int isBlockInteresting( const tr_torrent_t * tor,
const tr_peer_t * peer,
int block )
{
if( !isPieceInteresting( tor, peer, tr_blockPiece( block ) ) ) /* is piece interesting? */
return 0;
if( tr_cpBlockIsComplete( tor->completion, block )) /* we already have it */
return 0;
return 1;
+1 -1
View File
@@ -495,7 +495,7 @@ tr_bitfieldHas( const tr_bitfield_t * bitfield,
{
if ( bitfield == NULL ) return 0;
assert( bit / 8u < bitfield->len );
return ( bitfield->bits[ bit/8u ] & bitmask[bit%8] );
return ( bitfield->bits[ bit/8u ] & bitmask[bit%8] ) != 0;
}
void