Changeset 6652


Ignore:
Timestamp:
Aug 27, 2008, 6:50:21 PM (13 years ago)
Author:
charles
Message:

(libT) maybe fix the hangs reported by users in the recent nightlies.

Location:
trunk/libtransmission
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/crypto.c

    r6518 r6652  
    269269}
    270270
    271 int tr_cryptoRandInt( int sup )
     271int
     272tr_cryptoRandInt( int sup )
    272273{
    273274    int r;
     
    278279}
    279280
     281int
     282tr_cryptoWeakRandInt( int sup )
     283{
     284    static int init = 0;
     285    assert( sup > 0 );
     286
     287    if( !init )
     288    {
     289        srand( tr_date( ) );
     290        init = 1;
     291    }
     292
     293    return rand() % sup;
     294}
     295
    280296void tr_cryptoRandBuf ( unsigned char *buf, size_t len )
    281297{
  • trunk/libtransmission/crypto.h

    r6517 r6652  
    8080int tr_cryptoRandInt ( int n );
    8181
     82/** Returns a vaguely random number in the range of [0...n).
     83    This is faster -- BUT WEAKER -- than tr_cryptoRandInt()
     84    and should only be used when tr_cryptoRandInt() is too
     85    slow, and NEVER in sensitive cases */
     86int tr_cryptoWeakRandInt( int n );
     87
    8288/** Fills a buffer with random bytes */
    8389void tr_cryptoRandBuf ( unsigned char *buf, size_t len );
  • trunk/libtransmission/peer-mgr.c

    r6634 r6652  
    131131**/
    132132
    133 /* The following is not a very high quality random number generator.  It
    134  * is mainly used as a simple stupid random number generator inside some
    135  * functions below. Please don't use it for anything else unless you
    136  * know what you're doing. Use tr_cryptoRandInt() instead.
    137  */
    138 
    139 static int
    140 tr_stupidRandInt( int sup )
    141 {
    142     static int init = 0;
    143     assert( sup > 0 );
    144 
    145     if( !init )
    146     {
    147         srand( tr_date() );
    148         init = 1;
    149     }
    150 
    151     return rand() % sup;
    152 }
    153 
    154133static void
    155134managerLock( const struct tr_peerMgr * manager )
     
    627606            setme->priority = inf->pieces[piece].priority;
    628607            setme->peerCount = 0;
    629             setme->random = tr_stupidRandInt( INT_MAX );
     608            setme->random = tr_cryptoWeakRandInt( INT_MAX );
    630609
    631610            for( k=0; k<peerCount; ++k ) {
     
    668647    if( retCount ) {
    669648        tr_peer ** tmp = tr_new( tr_peer*, retCount );
    670         i = tr_stupidRandInt( retCount );
     649        i = tr_cryptoWeakRandInt( retCount );
    671650        memcpy( tmp, ret, sizeof(tr_peer*) * retCount );
    672651        memcpy( ret, tmp+i, sizeof(tr_peer*) * (retCount-i) );
     
    16641643        if(( n = tr_ptrArraySize( randPool )))
    16651644        {
    1666             c = tr_ptrArrayNth( randPool, tr_stupidRandInt( n ));
     1645            c = tr_ptrArrayNth( randPool, tr_cryptoWeakRandInt( n ));
    16671646            c->doUnchoke = 1;
    16681647            t->optimistic = c->peer;
  • trunk/libtransmission/peer-msgs.c

    r6629 r6652  
    17671767{
    17681768    struct evbuffer * out = msgs->outMessages;
    1769     const tr_piece_index_t pieceCount = msgs->torrent->info.pieceCount;
    17701769    tr_bitfield * field;
    17711770    tr_piece_index_t lazyPieces[LAZY_PIECE_COUNT];
    1772     int i;
    1773     int lazyCount = 0;
     1771    size_t i;
     1772    size_t lazyCount = 0;
    17741773
    17751774    field = tr_bitfieldDup( tr_cpPieceBitfield( msgs->torrent->completion ) );
     
    17771776    if( tr_sessionIsLazyBitfieldEnabled( msgs->session ) )
    17781777    {
    1779         const int maxLazyCount = MIN( LAZY_PIECE_COUNT, pieceCount );
    1780 
    1781         while( lazyCount < maxLazyCount )
     1778        /** Lazy bitfields aren't a high priority or secure, so I'm opting for
     1779            speed over a truly random sample -- let's limit the pool size to
     1780            the first 1000 pieces so large torrents don't bog things down */
     1781        size_t poolSize = MIN( msgs->torrent->info.pieceCount, 1000 );
     1782        tr_piece_index_t * pool = tr_new( tr_piece_index_t, poolSize );
     1783
     1784        /* build the pool */
     1785        for( i=0; i<poolSize; ++i )
     1786            pool[i] = i;
     1787        poolSize = i;
     1788
     1789        /* pull random piece indices from the pool */
     1790        while( ( poolSize > 0 ) && ( lazyCount < LAZY_PIECE_COUNT ) )
    17821791        {
    1783             const size_t pos = tr_cryptoRandInt ( pieceCount );
    1784             if( !tr_bitfieldHas( field, pos ) ) /* already removed it */
    1785                 continue;
    1786             dbgmsg( msgs, "lazy bitfield #%d: piece %d of %d",
    1787                     (int)(lazyCount+1), (int)pos, (int)pieceCount );
    1788             tr_bitfieldRem( field, pos );
    1789             lazyPieces[lazyCount++] = pos;
     1792            const int pos = tr_cryptoWeakRandInt( poolSize );
     1793            const tr_piece_index_t piece = pool[pos];
     1794            tr_bitfieldRem( field, piece );
     1795            lazyPieces[lazyCount++] = piece;
     1796            pool[pos] = pool[--poolSize];
    17901797        }
     1798
     1799        /* cleanup */
     1800        tr_free( pool );
    17911801    }
    17921802
Note: See TracChangeset for help on using the changeset viewer.