Changeset 7618


Ignore:
Timestamp:
Jan 5, 2009, 4:27:54 AM (12 years ago)
Author:
charles
Message:

(trunk libT) fix the much-hated "Assertion failed: (tr_isPeerIo( io ))". Also, repeated calls to tr_date() were taking up about 78% of the time in tr_stat(), so instead of calling multiple times, call it once in tr_stat() and pass that value around to the functions that need it.

Location:
trunk/libtransmission
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/bandwidth.c

    r7614 r7618  
    3434
    3535static float
    36 getSpeed( const struct bratecontrol * r, int interval_msec )
     36getSpeed( const struct bratecontrol * r, int interval_msec, uint64_t now )
    3737{
    3838    uint64_t       bytes = 0;
    39     const uint64_t cutoff = tr_date ( ) - interval_msec;
     39    const uint64_t cutoff = (now?now:tr_date()) - interval_msec;
    4040    int            i = r->newest;
    4141
     
    205205    peers = (struct tr_peerIo**) tr_ptrArrayBase( &tmp );
    206206    peerCount = tr_ptrArraySize( &tmp );
     207
     208    for( i=0; i<peerCount; ++i )
     209        tr_peerIoRef( peers[i] );
    207210
    208211    /* Stop all peers from listening for the socket to be ready for IO.
     
    247250            tr_peerIoSetEnabled( peers[i], dir, TRUE );
    248251
     252    for( i=0; i<peerCount; ++i )
     253        tr_peerIoUnref( peers[i] );
     254
    249255    /* cleanup */
    250256    tr_ptrArrayDestruct( &tmp, NULL );
     
    285291
    286292double
    287 tr_bandwidthGetRawSpeed( const tr_bandwidth * b, tr_direction dir )
    288 {
    289     assert( tr_isBandwidth( b ) );
    290     assert( tr_isDirection( dir ) );
    291 
    292     return getSpeed( &b->band[dir].raw, HISTORY_MSEC );
     293tr_bandwidthGetRawSpeed( const tr_bandwidth * b, const uint64_t now, const tr_direction dir )
     294{
     295    assert( tr_isBandwidth( b ) );
     296    assert( tr_isDirection( dir ) );
     297
     298    return getSpeed( &b->band[dir].raw, HISTORY_MSEC, now );
    293299}
    294300
    295301double
    296 tr_bandwidthGetPieceSpeed( const tr_bandwidth * b, tr_direction dir )
    297 {
    298     assert( tr_isBandwidth( b ) );
    299     assert( tr_isDirection( dir ) );
    300 
    301     return getSpeed( &b->band[dir].piece, HISTORY_MSEC );
     302tr_bandwidthGetPieceSpeed( const tr_bandwidth * b, const uint64_t now, const tr_direction dir )
     303{
     304    assert( tr_isBandwidth( b ) );
     305    assert( tr_isDirection( dir ) );
     306
     307    return getSpeed( &b->band[dir].piece, HISTORY_MSEC, now );
    302308}
    303309
  • trunk/libtransmission/bandwidth.h

    r7580 r7618  
    203203/** @brief Get the raw total of bytes read or sent by this bandwidth subtree. */
    204204double tr_bandwidthGetRawSpeed( const tr_bandwidth  * bandwidth,
    205                                 tr_direction          direction );
     205                                const uint64_t        now,
     206                                const tr_direction    direction );
    206207
    207208/** @brief Get the number of piece data bytes read or sent by this bandwidth subtree. */
    208209double tr_bandwidthGetPieceSpeed( const tr_bandwidth  * bandwidth,
    209                                   tr_direction          direction );
     210                                  const uint64_t        now,
     211                                  const tr_direction    direction );
    210212
    211213/**
  • trunk/libtransmission/handshake.c

    r7549 r7618  
    10961096{
    10971097    if( handshake->io )
    1098         tr_peerIoFree( handshake->io );
     1098        tr_peerIoUnref( handshake->io );
    10991099
    11001100    tr_free( handshake );
  • trunk/libtransmission/peer-io.c

    r7607 r7618  
    119119    dbgmsg( io, "canRead" );
    120120
     121    tr_peerIoRef( io );
     122
    121123    /* try to consume the input buffer */
    122124    if( io->canRead )
     
    160162        tr_globalUnlock( session );
    161163    }
     164
     165    tr_peerIoUnref( io );
    162166}
    163167
     
    167171    return ( io != NULL )
    168172        && ( io->magicNumber == MAGIC_NUMBER )
     173        && ( io->refCount > 0 )
    169174        && ( tr_isBandwidth( &io->bandwidth ) )
    170175        && ( tr_isAddress( &io->addr ) )
     
    345350    io = tr_new0( tr_peerIo, 1 );
    346351    io->magicNumber = MAGIC_NUMBER;
     352    io->refCount = 1;
    347353    io->crypto = tr_cryptoNew( torrentHash, isIncoming );
    348354    io->session = session;
     
    425431}
    426432
    427 void
     433static void
    428434tr_peerIoFree( tr_peerIo * io )
    429435{
     
    435441        tr_runInEventThread( io->session, io_dtor, io );
    436442    }
     443}
     444
     445void
     446tr_peerIoRef( tr_peerIo * io )
     447{
     448    assert( tr_isPeerIo( io ) );
     449
     450    ++io->refCount;
     451}
     452
     453void
     454tr_peerIoUnref( tr_peerIo * io )
     455{
     456    assert( tr_isPeerIo( io ) );
     457
     458    if( !--io->refCount )
     459        tr_peerIoFree( io );
    437460}
    438461
     
    570593
    571594static size_t
    572 getDesiredOutputBufferSize( const tr_peerIo * io )
     595getDesiredOutputBufferSize( const tr_peerIo * io, uint64_t now )
    573596{
    574597    /* this is all kind of arbitrary, but what seems to work well is
     
    577600     * It's okay to tweak this as needed */
    578601    const double maxBlockSize = 16 * 1024; /* 16 KiB is from BT spec */
    579     const double currentSpeed = tr_bandwidthGetPieceSpeed( &io->bandwidth, TR_UP );
     602    const double currentSpeed = tr_bandwidthGetPieceSpeed( &io->bandwidth, now, TR_UP );
    580603    const double period = 20; /* arbitrary */
    581604    const double numBlocks = 5.5; /* the 5 is arbitrary; the .5 is to leave room for messages */
     
    584607
    585608size_t
    586 tr_peerIoGetWriteBufferSpace( const tr_peerIo * io )
    587 {
    588     const size_t desiredLen = getDesiredOutputBufferSize( io );
     609tr_peerIoGetWriteBufferSpace( const tr_peerIo * io, uint64_t now )
     610{
     611    const size_t desiredLen = getDesiredOutputBufferSize( io, now );
    589612    const size_t currentLen = EVBUFFER_LENGTH( io->outbuf );
    590613    size_t freeSpace = 0;
  • trunk/libtransmission/peer-io.h

    r7616 r7618  
    6868
    6969    uint8_t               encryptionMode;
     70
    7071    tr_port               port;
    7172    int                   socket;
     73
     74    ssize_t               refCount;
    7275
    7376    uint8_t               peerId[SHA_DIGEST_LENGTH];
     
    111114                                  int                       socket );
    112115
    113 void        tr_peerIoFree       ( tr_peerIo               * io );
     116void tr_peerIoRef               ( tr_peerIo * io );
     117
     118void tr_peerIoUnref             ( tr_peerIo * io );
    114119
    115120tr_bool     tr_isPeerIo         ( const tr_peerIo         * io );
     
    310315**/
    311316
    312 size_t    tr_peerIoGetWriteBufferSpace( const tr_peerIo * io );
     317size_t    tr_peerIoGetWriteBufferSpace( const tr_peerIo * io, uint64_t now );
    313318
    314319static inline void tr_peerIoSetParent( tr_peerIo            * io,
     
    333338}
    334339
    335 static inline double tr_peerIoGetPieceSpeed( const tr_peerIo * io, tr_direction dir )
     340static inline double tr_peerIoGetPieceSpeed( const tr_peerIo * io, uint64_t now, tr_direction dir )
    336341{
    337342    assert( tr_isPeerIo( io ) );
    338343    assert( tr_isDirection( dir ) );
    339344
    340     return tr_bandwidthGetPieceSpeed( &io->bandwidth, dir );
     345    return tr_bandwidthGetPieceSpeed( &io->bandwidth, now, dir );
    341346}
    342347
  • trunk/libtransmission/peer-mgr-private.h

    r7580 r7618  
    7777
    7878double tr_peerGetPieceSpeed( const tr_peer    * peer,
     79                             uint64_t           now,
    7980                             tr_direction       direction );
    8081
  • trunk/libtransmission/peer-mgr.c

    r7614 r7618  
    145145    tr_ptrArray       torrents; /* Torrent */
    146146    tr_ptrArray       incomingHandshakes; /* tr_handshake */
    147     tr_ptrArray       finishedHandshakes; /* tr_handshake */
    148147    tr_timer        * bandwidthTimer;
    149148};
     
    357356    }
    358357
    359     tr_peerIoFree( peer->io );
     358    tr_peerIoUnref( peer->io );
    360359
    361360    tr_bitfieldFree( peer->have );
     
    460459    m->torrents = TR_PTR_ARRAY_INIT;
    461460    m->incomingHandshakes = TR_PTR_ARRAY_INIT;
    462     m->finishedHandshakes = TR_PTR_ARRAY_INIT;
    463461    m->bandwidthTimer = tr_timerNew( session, bandwidthPulse, m, BANDWIDTH_PERIOD_MSEC );
    464462    return m;
     
    468466tr_peerMgrFree( tr_peerMgr * manager )
    469467{
    470     tr_handshake * handshake;
    471 
    472468    managerLock( manager );
    473469
     
    480476
    481477    tr_ptrArrayDestruct( &manager->incomingHandshakes, NULL );
    482 
    483     while(( handshake = tr_ptrArrayPop( &manager->finishedHandshakes )))
    484         tr_handshakeFree( handshake );
    485 
    486     tr_ptrArrayDestruct( &manager->finishedHandshakes, NULL );
    487478
    488479    /* free the torrents. */
     
    12771268
    12781269    if( !success )
    1279         tr_ptrArrayAppend( &manager->finishedHandshakes, handshake );
     1270        tr_handshakeFree( handshake );
    12801271
    12811272    if( t )
     
    17941785    int webseedCount;
    17951786    float * ret;
     1787    uint64_t now;
    17961788
    17971789    assert( manager );
     
    18031795    assert( webseedCount == t->tor->info.webseedCount );
    18041796    ret = tr_new0( float, webseedCount );
     1797    now = tr_date( );
    18051798
    18061799    for( i=0; i<webseedCount; ++i )
    1807         if( !tr_webseedGetSpeed( webseeds[i], &ret[i] ) )
     1800        if( !tr_webseedGetSpeed( webseeds[i], now, &ret[i] ) )
    18081801            ret[i] = -1.0;
    18091802
     
    18131806
    18141807double
    1815 tr_peerGetPieceSpeed( const tr_peer * peer, tr_direction direction )
    1816 {
    1817     return peer->io ? tr_peerIoGetPieceSpeed( peer->io, direction ) : 0.0;
     1808tr_peerGetPieceSpeed( const tr_peer * peer, uint64_t now, tr_direction direction )
     1809{
     1810    return peer->io ? tr_peerIoGetPieceSpeed( peer->io, now, direction ) : 0.0;
    18181811}
    18191812
     
    18281821    const tr_peer ** peers;
    18291822    tr_peer_stat * ret;
     1823    uint64_t now;
    18301824
    18311825    assert( manager );
     
    18361830    peers = (const tr_peer**) tr_ptrArrayBase( &t->peers );
    18371831    ret = tr_new0( tr_peer_stat, size );
     1832    now = tr_date( );
    18381833
    18391834    for( i = 0; i < size; ++i )
     
    18541849        stat->progress           = peer->progress;
    18551850        stat->isEncrypted        = tr_peerIoIsEncrypted( peer->io ) ? 1 : 0;
    1856         stat->rateToPeer         = tr_peerGetPieceSpeed( peer, TR_CLIENT_TO_PEER );
    1857         stat->rateToClient       = tr_peerGetPieceSpeed( peer, TR_PEER_TO_CLIENT );
     1851        stat->rateToPeer         = tr_peerGetPieceSpeed( peer, now, TR_CLIENT_TO_PEER );
     1852        stat->rateToClient       = tr_peerGetPieceSpeed( peer, now, TR_PEER_TO_CLIENT );
    18581853        stat->peerIsChoked       = peer->peerIsChoked;
    18591854        stat->peerIsInterested   = peer->peerIsInterested;
     
    19381933    struct ChokeData * choke = tr_new0( struct ChokeData, peerCount );
    19391934    const int chokeAll = !tr_torrentIsPieceTransferAllowed( t->tor, TR_CLIENT_TO_PEER );
     1935    const uint64_t now = tr_date( );
    19401936
    19411937    assert( torrentIsLocked( t ) );
     
    19651961            n->isInterested = peer->peerIsInterested;
    19661962            n->isChoked     = peer->peerIsChoked;
    1967             n->rate         = tr_peerGetPieceSpeed( peer, TR_CLIENT_TO_PEER ) * 1024;
     1963            n->rate         = tr_peerGetPieceSpeed( peer, now, TR_CLIENT_TO_PEER ) * 1024;
    19681964        }
    19691965    }
     
    23742370bandwidthPulse( void * vmgr )
    23752371{
    2376     tr_handshake * handshake;
    23772372    tr_peerMgr * mgr = vmgr;
    23782373    managerLock( mgr );
     
    23852380    tr_bandwidthAllocate( mgr->session->bandwidth, TR_DOWN, BANDWIDTH_PERIOD_MSEC );
    23862381
    2387     /* free all the finished handshakes */
    2388     while(( handshake = tr_ptrArrayPop( &mgr->finishedHandshakes )))
    2389         tr_handshakeFree( handshake );
    2390 
    23912382    managerUnlock( mgr );
    23922383    return TRUE;
  • trunk/libtransmission/peer-msgs.c

    r7611 r7618  
    16391639
    16401640static int
    1641 ratePulse( void * vmsgs )
    1642 {
    1643     tr_peermsgs * msgs = vmsgs;
    1644     const double rateToClient = tr_peerGetPieceSpeed( msgs->peer, TR_PEER_TO_CLIENT );
     1641ratePulse( tr_peermsgs * msgs, uint64_t now )
     1642{
     1643    const double rateToClient = tr_peerGetPieceSpeed( msgs->peer, now, TR_PEER_TO_CLIENT );
    16451644    const int seconds = 10;
    16461645    const int floor = 8;
     
    16881687    **/
    16891688
    1690     if( ( tr_peerIoGetWriteBufferSpace( msgs->peer->io ) >= msgs->torrent->blockSize )
     1689    if( ( tr_peerIoGetWriteBufferSpace( msgs->peer->io, now ) >= msgs->torrent->blockSize )
    16911690        && popNextRequest( msgs, &req ) )
    16921691    {
     
    17481747    const time_t  now = time( NULL );
    17491748
    1750     ratePulse( msgs );
     1749    ratePulse( msgs, now );
    17511750
    17521751    pumpRequestQueue( msgs, now );
     
    21242123
    21252124    tr_peerIoSetIOFuncs( m->peer->io, canRead, didWrite, gotError, m );
    2126     ratePulse( m );
     2125    ratePulse( m, tr_date() );
    21272126
    21282127    return m;
  • trunk/libtransmission/ratecontrol.c

    r7584 r7618  
    3333static float
    3434rateForInterval( const tr_ratecontrol * r,
    35                  int                    interval_msec )
     35                 int                    interval_msec,
     36                 uint64_t               now )
    3637{
    3738    uint64_t       bytes = 0;
    38     const uint64_t cutoff = tr_date ( ) - interval_msec;
     39    const uint64_t cutoff = (now?now:tr_date()) - interval_msec;
    3940    int            i = r->newest;
    4041
     
    5859
    5960float
    60 tr_rcRate( const tr_ratecontrol * r )
     61tr_rcRate( const tr_ratecontrol * r, uint64_t now )
    6162{
    6263    float ret = 0.0f;
    6364
    6465    if( r )
    65         ret = rateForInterval( r, TR_RC_HISTORY_MSEC );
     66        ret = rateForInterval( r, TR_RC_HISTORY_MSEC, now );
    6667
    6768    return ret;
  • trunk/libtransmission/ratecontrol.h

    r7584 r7618  
    7171                                    size_t                   byteCount );
    7272
    73 float            tr_rcRate        ( const tr_ratecontrol   * ratecontrol );
     73float            tr_rcRate        ( const tr_ratecontrol   * ratecontrol,
     74                                    uint64_t                 now );
    7475
    7576
  • trunk/libtransmission/session.c

    r7580 r7618  
    736736tr_sessionGetPieceSpeed( const tr_session * session, tr_direction dir )
    737737{
    738     return session ? tr_bandwidthGetPieceSpeed( session->bandwidth, dir ) : 0.0;
     738    return session ? tr_bandwidthGetPieceSpeed( session->bandwidth, 0, dir ) : 0.0;
    739739}
    740740
     
    742742tr_sessionGetRawSpeed( const tr_session * session, tr_direction dir )
    743743{
    744     return session ? tr_bandwidthGetPieceSpeed( session->bandwidth, dir ) : 0.0;
     744    return session ? tr_bandwidthGetPieceSpeed( session->bandwidth, 0, dir ) : 0.0;
    745745}
    746746
  • trunk/libtransmission/torrent.c

    r7601 r7618  
    723723    const tr_tracker_info * ti;
    724724    int                     usableSeeds = 0;
     725    uint64_t                now;
    725726
    726727    if( !tor )
     
    759760                            s->peersFrom );
    760761
    761     s->rawUploadSpeed     = tr_bandwidthGetRawSpeed  ( tor->bandwidth, TR_UP );
    762     s->rawDownloadSpeed   = tr_bandwidthGetRawSpeed  ( tor->bandwidth, TR_DOWN );
    763     s->pieceUploadSpeed   = tr_bandwidthGetPieceSpeed( tor->bandwidth, TR_UP );
    764     s->pieceDownloadSpeed = tr_bandwidthGetPieceSpeed( tor->bandwidth, TR_DOWN );
     762    now = tr_date( );
     763    s->swarmSpeed         = tr_rcRate( &tor->swarmSpeed, now );
     764    s->rawUploadSpeed     = tr_bandwidthGetRawSpeed  ( tor->bandwidth, now, TR_UP );
     765    s->rawDownloadSpeed   = tr_bandwidthGetRawSpeed  ( tor->bandwidth, now, TR_DOWN );
     766    s->pieceUploadSpeed   = tr_bandwidthGetPieceSpeed( tor->bandwidth, now, TR_UP );
     767    s->pieceDownloadSpeed = tr_bandwidthGetPieceSpeed( tor->bandwidth, now, TR_DOWN );
    765768
    766769    usableSeeds += tor->info.webseedCount;
     
    778781                       : 0.0;
    779782
    780     s->swarmSpeed = tr_rcRate( &tor->swarmSpeed );
    781783
    782784    s->activityDate = tor->activityDate;
  • trunk/libtransmission/webseed.c

    r7584 r7618  
    253253
    254254int
    255 tr_webseedGetSpeed( const tr_webseed * w, float * setme_KiBs )
     255tr_webseedGetSpeed( const tr_webseed * w, uint64_t now, float * setme_KiBs )
    256256{
    257257    const int isActive = tr_webseedIsActive( w );
    258258
    259     *setme_KiBs = isActive ? tr_rcRate( &w->rateDown ) : 0.0f;
     259    *setme_KiBs = isActive ? tr_rcRate( &w->rateDown, now ) : 0.0f;
    260260    return isActive;
    261261}
  • trunk/libtransmission/webseed.h

    r7404 r7618  
    3737/** @return true if a request is being processed, or false if idle */
    3838int         tr_webseedGetSpeed( const tr_webseed * w,
     39                                uint64_t           now,
    3940                                float *            setme_KiBs );
    4041
Note: See TracChangeset for help on using the changeset viewer.