From 03351e9a4e2c6682b688e3cbb3c068286271e890 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 29 Nov 2009 18:35:02 +0000 Subject: [PATCH] (trunk libT) #2607 "avoid unnecessary calls to getPeerCandidates(), wasted cycles in peerIsInUse()" --- libtransmission/peer-mgr.c | 176 +++++++++++++++++++++---------------- 1 file changed, 99 insertions(+), 77 deletions(-) diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 6520a1880..f5f3ba17f 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -1559,7 +1559,7 @@ tr_peerMgrAddIncoming( tr_peerMgr * manager, { tr_netClose( session, socket ); } - else /* we don't have a connetion to them yet... */ + else /* we don't have a connection to them yet... */ { tr_peerIo * io; tr_handshake * handshake; @@ -2523,10 +2523,6 @@ getPeerCandidates( Torrent * t, const time_t now, int * setmeSize ) if( atom->myflags & MYFLAG_UNREACHABLE ) continue; - /* we don't need two connections to the same peer... */ - if( peerIsInUse( t, atom ) ) - continue; - /* no need to connect if we're both seeds... */ if( seed && ( ( atom->flags & ADDED_F_SEED_FLAG ) || ( atom->uploadOnly == UPLOAD_ONLY_YES ) ) ) @@ -2545,10 +2541,15 @@ getPeerCandidates( Torrent * t, const time_t now, int * setmeSize ) if( tr_sessionIsAddressBlocked( t->manager->session, &atom->addr ) ) continue; + /* we don't need two connections to the same peer... */ + if( peerIsInUse( t, atom ) ) + continue; + ret[retCount++] = atom; } - qsort( ret, retCount, sizeof( struct peer_atom* ), compareCandidates ); + if( retCount != 0 ) + qsort( ret, retCount, sizeof( struct peer_atom* ), compareCandidates ); *setmeSize = retCount; return ret; } @@ -2595,92 +2596,113 @@ reconnectTorrent( Torrent * t ) else { int i; - int canCloseCount; int mustCloseCount; - int candidateCount; int maxCandidates; - struct tr_peer ** canClose = getPeersToClose( t, TR_CAN_CLOSE, now, &canCloseCount ); - struct tr_peer ** mustClose = getPeersToClose( t, TR_MUST_CLOSE, now, &mustCloseCount ); - struct peer_atom ** candidates = getPeerCandidates( t, now, &candidateCount ); - - tordbg( t, "reconnect pulse for [%s]: " - "%d must-close connections, " - "%d can-close connections, " - "%d connection candidates, " - "%d atoms, " - "max per pulse is %d", - tr_torrentName( t->tor ), - mustCloseCount, - canCloseCount, - candidateCount, - tr_ptrArraySize( &t->pool ), - MAX_RECONNECTIONS_PER_PULSE ); + struct tr_peer ** mustClose; /* disconnect the really bad peers */ + mustClose = getPeersToClose( t, TR_MUST_CLOSE, now, &mustCloseCount ); for( i=0; itor ) - getPeerCount( t ) ); maxCandidates = MIN( maxCandidates, MAX_CONNECTIONS_PER_SECOND - newConnectionsThisSecond ); - /* maybe disconnect some lesser peers, if we have candidates to replace them with */ - for( i=0; ( itor ), - newConnectionsThisSecond, MAX_CONNECTIONS_PER_SECOND ); - - /* add some new ones */ - for( i=0; imanager; - struct peer_atom * atom = candidates[i]; - tr_peerIo * io; + tordbg( t, "reconnect pulse for [%s]: %d must-close connections, " + "NO connection candidates needed, %d atoms, " + "max per pulse is %d", + t->tor->info.name, mustCloseCount, + tr_ptrArraySize( &t->pool ), + MAX_RECONNECTIONS_PER_PULSE ); - tordbg( t, "Starting an OUTGOING connection with %s", - tr_atomAddrStr( atom ) ); - - io = tr_peerIoNewOutgoing( mgr->session, mgr->session->bandwidth, &atom->addr, atom->port, t->tor->info.hash ); - - if( io == NULL ) - { - tordbg( t, "peerIo not created; marking peer %s as unreachable", - tr_atomAddrStr( atom ) ); - atom->myflags |= MYFLAG_UNREACHABLE; - } - else - { - tr_handshake * handshake = tr_handshakeNew( io, - mgr->session->encryptionMode, - myHandshakeDoneCB, - mgr ); - - assert( tr_peerIoGetTorrentHash( io ) ); - - tr_peerIoUnref( io ); /* balanced by the implicit ref in tr_peerIoNewOutgoing() */ - - ++newConnectionsThisSecond; - - tr_ptrArrayInsertSorted( &t->outgoingHandshakes, handshake, - handshakeCompare ); - } - - atom->time = now; + tordbg( t, "maxCandidates is %d, MAX_RECONNECTIONS_PER_PULSE is %d, " + "getPeerCount(t) is %d, getMaxPeerCount(t) is %d, " + "newConnectionsThisSecond is %d, MAX_CONNECTIONS_PER_SECOND is %d", + maxCandidates, MAX_RECONNECTIONS_PER_PULSE, + getPeerCount( t ), getMaxPeerCount( t->tor ), + newConnectionsThisSecond, MAX_CONNECTIONS_PER_SECOND ); } + else + { + int canCloseCount = 0; + int candidateCount; + struct peer_atom ** candidates; - /* cleanup */ - tr_free( candidates ); - tr_free( mustClose ); - tr_free( canClose ); + candidates = getPeerCandidates( t, now, &candidateCount ); + maxCandidates = MIN( maxCandidates, candidateCount ); + + /* maybe disconnect some lesser peers, if we have candidates to replace them with */ + if( maxCandidates != 0 ) + { + struct tr_peer ** canClose = getPeersToClose( t, TR_CAN_CLOSE, now, &canCloseCount ); + for( i=0; ( itor->info.name, mustCloseCount, + canCloseCount, candidateCount, + tr_ptrArraySize( &t->pool ), MAX_RECONNECTIONS_PER_PULSE ); + + tordbg( t, "candidateCount is %d, MAX_RECONNECTIONS_PER_PULSE is %d," + " getPeerCount(t) is %d, getMaxPeerCount(t) is %d, " + "newConnectionsThisSecond is %d, MAX_CONNECTIONS_PER_SECOND is %d", + candidateCount, MAX_RECONNECTIONS_PER_PULSE, + getPeerCount( t ), getMaxPeerCount( t->tor ), + newConnectionsThisSecond, MAX_CONNECTIONS_PER_SECOND ); + + /* add some new ones */ + for( i=0; imanager; + struct peer_atom * atom = candidates[i]; + tr_peerIo * io; + + tordbg( t, "Starting an OUTGOING connection with %s", + tr_atomAddrStr( atom ) ); + + io = tr_peerIoNewOutgoing( mgr->session, + mgr->session->bandwidth, + &atom->addr, + atom->port, + t->tor->info.hash ); + + if( io == NULL ) + { + tordbg( t, "peerIo not created; marking peer %s as unreachable", + tr_atomAddrStr( atom ) ); + atom->myflags |= MYFLAG_UNREACHABLE; + } + else + { + tr_handshake * handshake = tr_handshakeNew( io, + mgr->session->encryptionMode, + myHandshakeDoneCB, + mgr ); + + assert( tr_peerIoGetTorrentHash( io ) ); + + tr_peerIoUnref( io ); /* balanced by the implicit ref in tr_peerIoNewOutgoing() */ + + ++newConnectionsThisSecond; + + tr_ptrArrayInsertSorted( &t->outgoingHandshakes, handshake, + handshakeCompare ); + } + + atom->time = now; + } + tr_free( candidates ); + } } }