mirror of
https://github.com/transmission/transmission.git
synced 2026-05-08 09:39:08 +01:00
fix endgame bugs
This commit is contained in:
+24
-5
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user