+
/*
* This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com>
*
tr_ptrArray pool; /* struct peer_atom */
tr_ptrArray peers; /* tr_peer */
tr_ptrArray webseeds; /* tr_webseed */
+ tr_timer * refillTimer;
tr_torrent * tor;
tr_peer * optimistic; /* the optimistic peer, or NULL if none */
tr_ptrArray incomingHandshakes; /* tr_handshake */
tr_timer * bandwidthTimer;
tr_timer * rechokeTimer;
- tr_timer * refillTimer;
tr_timer * reconnectTimer;
};
memcpy( hash, t->hash, SHA_DIGEST_LENGTH );
+ tr_timerFree( &t->refillTimer );
+
tr_ptrArrayDestruct( &t->webseeds, (PtrArrayForeachFunc)tr_webseedFree );
tr_ptrArrayDestruct( &t->pool, (PtrArrayForeachFunc)tr_free );
tr_ptrArrayDestruct( &t->outgoingHandshakes, NULL );
static int bandwidthPulse ( void * vmgr );
static int rechokePulse ( void * vmgr );
-static int refillPulse ( void * vmgr );
static int reconnectPulse ( void * vmgr );
tr_peerMgr*
m->incomingHandshakes = TR_PTR_ARRAY_INIT;
m->bandwidthTimer = tr_timerNew( session, bandwidthPulse, m, BANDWIDTH_PERIOD_MSEC );
m->rechokeTimer = tr_timerNew( session, rechokePulse, m, RECHOKE_PERIOD_MSEC );
- m->refillTimer = tr_timerNew( session, refillPulse, m, REFILL_PERIOD_MSEC );
m->reconnectTimer = tr_timerNew( session, reconnectPulse, m, RECONNECT_PERIOD_MSEC );
rechokePulse( m );
managerLock( manager );
tr_timerFree( &manager->reconnectTimer );
- tr_timerFree( &manager->refillTimer );
tr_timerFree( &manager->rechokeTimer );
tr_timerFree( &manager->bandwidthTimer );
return (uint32_t)( blockPos - piecePos );
}
-static void
-refillTorrent( Torrent * t )
+static int
+refillPulse( void * vtorrent )
{
tr_block_index_t block;
int peerCount;
tr_peer ** peers;
tr_webseed ** webseeds;
struct tr_blockIterator * blockIterator;
+ Torrent * t = vtorrent;
tr_torrent * tor = t->tor;
if( !t->isRunning )
- return;
+ return TRUE;
if( tr_torrentIsSeed( t->tor ) )
- return;
+ return TRUE;
+ torrentLock( t );
tordbg( t, "Refilling Request Buffers..." );
blockIterator = blockIteratorNew( t );
blockIteratorFree( blockIterator );
tr_free( webseeds );
tr_free( peers );
-}
-static int
-refillPulse( void * vmgr )
-{
- tr_torrent * tor = NULL;
- tr_peerMgr * mgr = vmgr;
- managerLock( mgr );
-
- while(( tor = tr_torrentNext( mgr->session, tor )))
- if( tor->isRunning && !tr_torrentIsSeed( tor ) )
- refillTorrent( tor->torrentPeers );
-
- managerUnlock( mgr );
- return TRUE;
+ t->refillTimer = NULL;
+ torrentUnlock( t );
+ return FALSE;
}
static void
tor->downloadedCur -= MIN( tor->downloadedCur, byteCount );
}
+static void
+refillSoon( Torrent * t )
+{
+ if( t->refillTimer == NULL )
+ t->refillTimer = tr_timerNew( t->manager->session,
+ refillPulse, t,
+ REFILL_PERIOD_MSEC );
+}
+
static void
peerSuggestedPiece( Torrent * t UNUSED,
tr_peer * peer UNUSED,
}
break;
+ case TR_PEER_NEED_REQ:
+ refillSoon( t );
+ break;
+
case TR_PEER_CANCEL:
decrementPieceRequests( t, e->pieceIndex );
break;
void
tr_peerMgrStartTorrent( tr_torrent * tor )
{
- tor->torrentPeers->isRunning = TRUE;
+ Torrent * t = tor->torrentPeers;
+
+ managerLock( t->manager );
+
+ assert( t );
+
+ if( !t->isRunning )
+ {
+ t->isRunning = TRUE;
+
+ if( !tr_ptrArrayEmpty( &t->webseeds ) )
+ refillSoon( t );
+ }
+
+ managerUnlock( t->manager );
}
static void
publish( msgs, &e );
}
+static void
+fireNeedReq( tr_peermsgs * msgs )
+{
+ tr_peer_event e = blankEvent;
+ e.eventType = TR_PEER_NEED_REQ;
+ publish( msgs, &e );
+}
+
static void
firePeerProgress( tr_peermsgs * msgs )
{
if( i != msgs->peer->clientIsInterested )
sendInterest( msgs, i );
+ if( i )
+ fireNeedReq( msgs );
}
static int
if( sent )
dbgmsg( msgs, "pump sent %d requests, now have %d active and %d queued",
sent, msgs->clientAskedFor.len, msgs->clientWillAskFor.len );
+
+ if( len < max )
+ fireNeedReq( msgs );
}
static TR_INLINE int
case BT_UNCHOKE:
dbgmsg( msgs, "got Unchoke" );
msgs->peer->clientIsChoked = 0;
+ fireNeedReq( msgs );
break;
case BT_INTERESTED:
break;
case BT_BITFIELD:
+ {
dbgmsg( msgs, "got a bitfield" );
tr_peerIoReadBytes( msgs->peer->io, inbuf, msgs->peer->have->bits, msglen );
updatePeerProgress( msgs );
+ fireNeedReq( msgs );
break;
+ }
case BT_REQUEST:
{