diff --git a/libtransmission/bitset.c b/libtransmission/bitset.c index 3e32feab0..317fffb7f 100644 --- a/libtransmission/bitset.c +++ b/libtransmission/bitset.c @@ -159,6 +159,28 @@ tr_bitsetCountRange( const tr_bitset * b, const size_t begin, const size_t end ) return tr_bitfieldCountRange( &b->bitfield, begin, end ); } +/* return true if "b" is equal to, or a superset of, "set" */ +tr_bool +tr_bitsetHasSet( const tr_bitset * b, const tr_bitset * set ) +{ + const uint8_t * bit = b->bitfield.bits; + const uint8_t * bend = bit + b->bitfield.byteCount; + const uint8_t * sit = set->bitfield.bits; + const uint8_t * send = sit + set->bitfield.byteCount; + + if( b->haveAll || set->haveAll ) + return b->haveAll; + + if( b->haveNone || set->haveNone ) + return set->haveNone; + + for( ; bit!=bend && sit!=send; ++bit, ++sit ) + if( ( *bit & *sit ) != *sit ) + return FALSE; + + return TRUE; +} + double tr_bitsetPercent( const tr_bitset * b ) { diff --git a/libtransmission/bitset.h b/libtransmission/bitset.h index b4f98a2ec..7fbbbf0c8 100644 --- a/libtransmission/bitset.h +++ b/libtransmission/bitset.h @@ -54,6 +54,7 @@ void tr_bitsetToBenc( const tr_bitset * bitset, struct tr_benc * benc ); double tr_bitsetPercent( const tr_bitset * b ); tr_bool tr_bitsetHas( const tr_bitset * b, const size_t nth ); +tr_bool tr_bitsetHasSet( const tr_bitset * b, const tr_bitset * compare ); size_t tr_bitsetCountRange( const tr_bitset * b, const size_t begin, const size_t end ); void tr_bitsetOr( tr_bitfield * a, const tr_bitset * b ); diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 941af04b4..2c97be2c9 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -3109,7 +3109,7 @@ shouldPeerBeClosed( const Torrent * t, /* if we're seeding and the peer has everything we have, * and enough time has passed for a pex exchange, then disconnect */ - if( tr_torrentIsSeed( tor ) && ( peer->progress >= 1.0f ) ) + if( tr_torrentIsSeed( tor ) && tr_bitsetHasSet( &peer->have, tr_cpBlockBitset( &tor->completion ) ) ) return !tr_torrentAllowsPex(tor) || (now-atom->time>=30); /* disconnect if it's been too long since piece data has been transferred.