(trunk libT) #4035 "In seed state, transmission disconnect from leechers" -- fixed.

This commit is contained in:
Jordan Lee 2011-02-24 14:35:45 +00:00
parent 6dc20636bb
commit 9d95bd151d
5 changed files with 64 additions and 35 deletions

View File

@ -61,7 +61,6 @@ typedef enum
TR_PEER_CLIENT_GOT_HAVE_ALL,
TR_PEER_CLIENT_GOT_HAVE_NONE,
TR_PEER_PEER_GOT_DATA,
TR_PEER_PEER_PROGRESS,
TR_PEER_ERROR
}
PeerEventType;
@ -74,7 +73,6 @@ typedef struct
struct tr_bitfield * bitfield; /* for GOT_BITFIELD */
uint32_t offset; /* for GOT_BLOCK */
uint32_t length; /* for GOT_BLOCK + GOT_DATA */
float progress; /* for PEER_PROGRESS */
int err; /* errno for GOT_ERROR */
tr_bool wasPieceData; /* for GOT_DATA */
tr_port port; /* for GOT_PORT */
@ -89,6 +87,10 @@ typedef void tr_peer_callback( struct tr_peer * peer,
const tr_peer_event * event,
void * client_data );
/** Update the tr_peer.progress field based on the 'have' bitset. */
void tr_peerUpdateProgress( tr_torrent * tor, struct tr_peer * );
#ifdef WIN32
#define EMSGSIZE WSAEMSGSIZE
#endif

View File

@ -99,7 +99,7 @@ enum
CANCEL_HISTORY_SEC = 60
};
const tr_peer_event TR_PEER_EVENT_INIT = { 0, 0, NULL, 0, 0, 0.0f, 0, FALSE, 0 };
const tr_peer_event TR_PEER_EVENT_INIT = { 0, 0, NULL, 0, 0, 0, FALSE, 0 };
/**
***
@ -645,18 +645,24 @@ atomSetSeedProbability( struct peer_atom * atom, int seedProbability )
atom->flags &= ~ADDED_F_SEED_FLAG;
}
static void
atomSetSeed( struct peer_atom * atom )
{
atomSetSeedProbability( atom, 100 );
}
static inline tr_bool
atomIsSeed( const struct peer_atom * atom )
{
return atom->seedProbability == 100;
}
static void
atomSetSeed( const Torrent * t, struct peer_atom * atom )
{
if( !atomIsSeed( atom ) )
{
tordbg( t, "marking peer %s as a seed", tr_atomAddrStr( atom ) );
atomSetSeedProbability( atom, 100 );
}
}
tr_bool
tr_peerMgrPeerIsSeed( const tr_torrent * tor,
const tr_address * addr )
@ -1699,19 +1705,6 @@ peerCallbackFunc( tr_peer * peer, const tr_peer_event * e, void * vt )
break;
}
case TR_PEER_PEER_PROGRESS:
{
if( peer )
{
struct peer_atom * atom = peer->atom;
if( e->progress >= 1.0 ) {
tordbg( t, "marking peer %s as a seed", tr_atomAddrStr( atom ) );
atomSetSeed( atom );
}
}
break;
}
case TR_PEER_CLIENT_GOT_BLOCK:
{
tr_torrent * tor = t->tor;
@ -2109,7 +2102,7 @@ tr_peerMgrMarkAllAsSeeds( tr_torrent * tor )
struct peer_atom ** end = it + n;
while( it != end )
atomSetSeed( *it++ );
atomSetSeed( t, *it++ );
}
tr_pex *
@ -2442,6 +2435,46 @@ tr_peerMgrRemoveTorrent( tr_torrent * tor )
torrentFree( tor->torrentPeers );
}
void
tr_peerUpdateProgress( tr_torrent * tor, tr_peer * peer )
{
const tr_bitset * have = &peer->have;
if( have->haveAll )
{
peer->progress = 1.0;
}
else if( have->haveNone )
{
peer->progress = 0.0;
}
else
{
const float trueCount = tr_bitfieldCountTrueBits( &have->bitfield );
if( tr_torrentHasMetadata( tor ) )
peer->progress = trueCount / tor->info.pieceCount;
else /* without pieceCount, this result is only a best guess... */
peer->progress = trueCount / ( have->bitfield.bitCount + 1 );
}
if( peer->progress >= 1.0 )
atomSetSeed( tor->torrentPeers, peer->atom );
}
void
tr_peerMgrOnTorrentGotMetainfo( tr_torrent * tor )
{
int i;
const int peerCount = tr_ptrArraySize( &tor->torrentPeers->peers );
tr_peer ** peers = (tr_peer**) tr_ptrArrayBase( &tor->torrentPeers->peers );
/* some peer_msgs' progress fields may not be accurate if we
didn't have the metadata before now... so refresh them all... */
for( i=0; i<peerCount; ++i )
tr_peerUpdateProgress( tor, peers[i] );
}
void
tr_peerMgrTorrentAvailability( const tr_torrent * tor, int8_t * tab, unsigned int tabCount )
{

View File

@ -231,6 +231,8 @@ void tr_peerMgrTorrentAvailability( const tr_torrent * tor,
struct tr_bitfield* tr_peerMgrGetAvailable( const tr_torrent * tor );
void tr_peerMgrOnTorrentGotMetainfo( tr_torrent * tor );
void tr_peerMgrOnBlocklistChanged( tr_peerMgr * manager );
void tr_peerMgrTorrentStats( tr_torrent * tor,

View File

@ -455,15 +455,6 @@ fireError( tr_peermsgs * msgs, int err )
publish( msgs, &e );
}
static void
firePeerProgress( tr_peermsgs * msgs )
{
tr_peer_event e = TR_PEER_EVENT_INIT;
e.eventType = TR_PEER_PEER_PROGRESS;
e.progress = msgs->peer->progress;
publish( msgs, &e );
}
static void
fireGotBlock( tr_peermsgs * msgs, const struct peer_request * req )
{
@ -1208,11 +1199,10 @@ readBtId( tr_peermsgs * msgs, struct evbuffer * inbuf, size_t inlen )
static void
updatePeerProgress( tr_peermsgs * msgs )
{
msgs->peer->progress = tr_bitsetPercent( &msgs->peer->have );
dbgmsg( msgs, "peer progress is %f", msgs->peer->progress );
tr_peerUpdateProgress( msgs->torrent, msgs->peer );
updateFastSet( msgs );
updateInterest( msgs );
firePeerProgress( msgs );
}
static void

View File

@ -752,6 +752,8 @@ tr_torrentGotNewInfoDict( tr_torrent * tor )
{
torrentInitFromInfo( tor );
tr_peerMgrOnTorrentGotMetainfo( tor );
tr_torrentFireMetadataCompleted( tor );
}