Changeset 6882


Ignore:
Timestamp:
Oct 11, 2008, 4:07:50 AM (13 years ago)
Author:
charles
Message:

possible fix for #1305 "Transmission losing data - Session Transfer significantly higher than actual download". This patch may need more user testing and will definitely make webseeds slower. suck it up.

Location:
trunk/libtransmission
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/peer-mgr.c

    r6878 r6882  
    115115    tr_torrent *    tor;
    116116    tr_peer *       optimistic; /* the optimistic peer, or NULL if none */
    117     tr_bitfield *   requestedPieces;
     117    tr_bitfield *   requestedBlocks;
    118118
    119119    unsigned int    isRunning : 1;
     
    406406    tr_timerFree( &t->refillTimer );
    407407
    408     tr_bitfieldFree( t->requestedPieces );
     408    tr_bitfieldFree( t->requestedBlocks );
    409409    tr_ptrArrayFree( t->webseeds, (PtrArrayForeachFunc)tr_webseedFree );
    410410    tr_ptrArrayFree( t->pool, (PtrArrayForeachFunc)tr_free );
     
    433433    t->webseeds = tr_ptrArrayNew( );
    434434    t->outgoingHandshakes = tr_ptrArrayNew( );
    435     t->requestedPieces = tr_bitfieldNew( tor->info.pieceCount );
     435    t->requestedBlocks = tr_bitfieldNew( tor->blockCount );
    436436    memcpy( t->hash, tor->info.hash, SHA_DIGEST_LENGTH );
    437437
     
    594594struct tr_refill_piece
    595595{
     596    int              missingBlockCount;
    596597    tr_priority_t    priority;
    597598    int              random;
     
    606607    const struct tr_refill_piece * a = aIn;
    607608    const struct tr_refill_piece * b = bIn;
     609
     610    /* fewer missing pieces goes first */
     611    if( a->missingBlockCount != b->missingBlockCount )
     612        return a->missingBlockCount < b->missingBlockCount ? -1 : 1;
    608613
    609614    /* if one piece has a higher priority, it goes first */
     
    672677            setme->peerCount = 0;
    673678            setme->random = tr_cryptoWeakRandInt( INT_MAX );
     679            setme->missingBlockCount = tr_cpMissingBlocksInPiece( tor->completion, piece );
    674680
    675681            for( k = 0; k < peerCount; ++k )
     
    697703}
    698704
     705static uint64_t*
     706getPreferredBlocks( Torrent * t, tr_block_index_t * setmeCount )
     707{
     708    int s;
     709    uint32_t i;
     710    uint32_t pieceCount;
     711    uint32_t blockCount;
     712    uint32_t unreqCount[3], reqCount[3];
     713    uint32_t * pieces;
     714    uint64_t * ret, * walk;
     715    uint64_t * unreq[3], *req[3];
     716    const tr_torrent * tor = t->tor;
     717
     718    assert( torrentIsLocked( t ) );
     719
     720    pieces = getPreferredPieces( t, &pieceCount );
     721
     722    /**
     723     * Now we walk through those preferred pieces to find all the blocks
     724     * are still missing from them.  We put unrequested blocks first,
     725     * of course, but by including requested blocks afterwards, endgame
     726     * handling happens naturally.
     727     *
     728     * By doing this once per priority we also effectively get an endgame
     729     * mode for each priority level.  The helps keep high priority files
     730     * from getting stuck at 99% due of unresponsive peers.
     731     */
     732
     733    /* make temporary bins for the four tiers of blocks */
     734    for( i=0; i<3; ++i ) {
     735        req[i] = tr_new( uint64_t, pieceCount *  tor->blockCountInPiece );
     736        reqCount[i] = 0;
     737        unreq[i] = tr_new( uint64_t, pieceCount *  tor->blockCountInPiece );
     738        unreqCount[i] = 0;
     739    }
     740
     741    /* sort the blocks into our temp bins */
     742    for( i=blockCount=0; i<pieceCount; ++i )
     743    {
     744        const tr_piece_index_t index = pieces[i];
     745        const int priorityIndex = tor->info.pieces[index].priority + 1;
     746        const tr_block_index_t begin = tr_torPieceFirstBlock( tor, index );
     747        const tr_block_index_t end = begin + tr_torPieceCountBlocks( tor, index );
     748        tr_block_index_t block;
     749
     750        assert( tr_bitfieldTestFast( t->requestedBlocks, end-1 ) );
     751
     752        for( block=begin; block<end; ++block )
     753        {
     754            if( tr_cpBlockIsComplete( tor->completion, block ) )
     755                continue;
     756
     757            ++blockCount;
     758
     759            if( tr_bitfieldHasFast( t->requestedBlocks, block ) )
     760            {
     761                const uint32_t n = reqCount[priorityIndex]++;
     762                req[priorityIndex][n] = block;
     763            }
     764            else
     765            {
     766                const uint32_t n = unreqCount[priorityIndex]++;
     767                unreq[priorityIndex][n] = block;
     768            }
     769        }
     770    }
     771
     772    /* join the bins together, going from highest priority to lowest so
     773     * the the blocks we want to request first will be first in the list */
     774    ret = walk = tr_new( uint64_t, blockCount );
     775    for( s=2; s>=0; --s ) {
     776        memcpy( walk, unreq[s], sizeof(uint64_t) * unreqCount[s] );
     777        walk += unreqCount[s];
     778        memcpy( walk, req[s], sizeof(uint64_t) * reqCount[s] );
     779        walk += reqCount[s];
     780    }
     781    assert( ( walk - ret ) == ( int )blockCount );
     782    *setmeCount = blockCount;
     783
     784    /* cleanup */
     785    tr_free( pieces );
     786    for( i=0; i<3; ++i ) {
     787        tr_free( unreq[i] );
     788        tr_free( req[i] );
     789    }
     790    return ret;
     791}
     792
    699793static tr_peer**
    700794getPeersUploadingToClient( Torrent * t,
     
    733827    Torrent *        t = vtorrent;
    734828    tr_torrent *     tor = t->tor;
     829    tr_block_index_t i;
    735830    int              peerCount;
    736831    int              webseedCount;
    737832    tr_peer **       peers;
    738833    tr_webseed **    webseeds;
    739     uint32_t         pieceCount;
    740     uint32_t *       pieces;
    741     tr_piece_index_t i;
     834    tr_block_index_t blockCount;
     835    uint64_t       * blocks;
    742836
    743837    if( !t->isRunning )
     
    749843    tordbg( t, "Refilling Request Buffers..." );
    750844
    751     pieces = getPreferredPieces( t, &pieceCount );
     845    blocks = getPreferredBlocks( t, &blockCount );
    752846    peers = getPeersUploadingToClient( t, &peerCount );
    753847    webseedCount = tr_ptrArraySize( t->webseeds );
     
    756850                         sizeof( tr_webseed* ) );
    757851
    758     for( i = 0; ( webseedCount || peerCount ) && i < pieceCount; ++i )
    759     {
    760         int                    j;
    761         int                    handled = FALSE;
    762         const tr_piece_index_t piece = pieces[i];
    763 
    764         assert( piece < tor->info.pieceCount );
    765 
    766         /* find a peer who can ask for this piece */
     852    for( i = 0; ( webseedCount || peerCount ) && i < blockCount; ++i )
     853    {
     854        int j;
     855        int handled = FALSE;
     856
     857        const tr_block_index_t block = blocks[i];
     858        const tr_piece_index_t index = tr_torBlockPiece( tor, block );
     859        const uint32_t begin = (block * tor->blockSize) - (index * tor->info.pieceSize);
     860        const uint32_t length = tr_torBlockCountBytes( tor, block );
     861
     862        assert( tr_torrentReqIsValid( tor, index, begin, length ) );
     863        assert( _tr_block( tor, index, begin ) == block );
     864        assert( begin < tr_torPieceCountBytes( tor, index ) );
     865        assert( (begin + length) <= tr_torPieceCountBytes( tor, index ) );
     866
     867        /* find a peer who can ask for this block */
    767868        for( j = 0; !handled && j < peerCount; )
    768869        {
    769             const tr_addreq_t val = tr_peerMsgsAddRequest( peers[j]->msgs,
    770                                                            piece );
     870            const int val = tr_peerMsgsAddRequest( peers[j]->msgs, index, begin, length );
    771871            switch( val )
    772872            {
     
    782882
    783883                case TR_ADDREQ_OK:
    784                     tr_bitfieldAdd( t->requestedPieces, piece );
     884                    tr_bitfieldAdd( t->requestedBlocks, block );
    785885                    handled = TRUE;
    786886                    break;
     
    795895        for( j = 0; !handled && j < webseedCount; )
    796896        {
    797             const tr_addreq_t val = tr_webseedAddRequest( webseeds[j],
    798                                                           piece );
     897            const tr_addreq_t val = tr_webseedAddRequest( webseeds[j], index, begin, length );
    799898            switch( val )
    800899            {
     
    804903
    805904                case TR_ADDREQ_OK:
    806                     tr_bitfieldAdd( t->requestedPieces, piece );
     905                    tr_bitfieldAdd( t->requestedBlocks, block );
    807906                    handled = TRUE;
    808907                    break;
     
    818917    tr_free( webseeds );
    819918    tr_free( peers );
    820     tr_free( pieces );
     919    tr_free( blocks );
    821920
    822921    t->refillTimer = NULL;
    823922    torrentUnlock( t );
    824923    return FALSE;
     924}
     925
     926static void
     927broadcastGotBlock( Torrent * t, uint32_t index, uint32_t offset, uint32_t length )
     928{
     929    int i, size;
     930    tr_peer ** peers;
     931
     932    assert( torrentIsLocked( t ) );
     933
     934    peers = getConnectedPeers( t, &size );
     935    for( i=0; i<size; ++i )
     936        tr_peerMsgsCancel( peers[i]->msgs, index, offset, length );
     937    tr_free( peers );
    825938}
    826939
     
    881994
    882995        case TR_PEER_CANCEL:
    883             tr_bitfieldRem( t->requestedPieces, e->pieceIndex );
     996            tr_bitfieldRem( t->requestedBlocks, _tr_block( t->tor, e->pieceIndex, e->offset ) );
    884997            break;
    885998
     
    9141027                tor->downloadedCur += e->length;
    9151028            tr_statsAddDownloaded( tor->session, e->length );
    916             if( peer )
    917             {
    918                 struct peer_atom * atom = getExistingAtom( t,
    919                                                            &peer->in_addr );
     1029            if( peer ) {
     1030                struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
    9201031                atom->piece_data_time = time( NULL );
    9211032            }
     
    9561067
    9571068            tr_cpBlockAdd( tor->completion, block );
     1069
     1070            broadcastGotBlock( t, e->pieceIndex, e->offset, e->length );
    9581071
    9591072            if( tr_cpPieceIsComplete( tor->completion, e->pieceIndex ) )
  • trunk/libtransmission/peer-msgs.c

    r6880 r6882  
    199199}
    200200
    201 static void
    202 reqListAppendPiece( const tr_torrent *    tor,
    203                     struct request_list * list,
    204                     tr_piece_index_t      piece )
    205 {
    206     const time_t           now = time( NULL );
    207     const size_t           n = tr_torPieceCountBlocks( tor, piece );
    208     const tr_block_index_t begin = tr_torPieceFirstBlock( tor, piece );
    209     const tr_block_index_t end = begin + n;
    210     tr_block_index_t       i;
    211 
    212     if( list->count + n >= list->max )
    213         reqListReserve( list, list->max + n );
    214 
    215     for( i = begin; i < end; ++i )
    216     {
    217         if( !tr_cpBlockIsComplete( tor->completion, i ) )
    218         {
    219             struct peer_request * req = list->requests + list->count++;
    220             req->index = piece;
    221             req->offset =
    222                 ( i * tor->blockSize ) - ( piece * tor->info.pieceSize );
    223             req->length = tr_torBlockCountBytes( tor, i );
    224             req->time_requested = now;
    225             assert( tr_torrentReqIsValid( tor, req->index, req->offset,
    226                                           req->length ) );
    227         }
    228     }
    229 }
    230 
    231201static int
    232202reqListPop( struct request_list * list,
     
    244214
    245215    return success;
    246 }
    247 
    248 static int
    249 reqListHasPiece( struct request_list *  list,
    250                  const tr_piece_index_t piece )
    251 {
    252     uint16_t i;
    253 
    254     for( i = 0; i < list->count; ++i )
    255         if( list->requests[i].index == piece )
    256             return 1;
    257 
    258     return 0;
    259216}
    260217
     
    549506
    550507static void
    551 fireCancelledReq( tr_peermsgs *          msgs,
    552                   const tr_piece_index_t pieceIndex )
     508fireCancelledReq( tr_peermsgs * msgs, const struct peer_request * req )
    553509{
    554510    tr_peer_event e = blankEvent;
    555 
    556511    e.eventType = TR_PEER_CANCEL;
    557     e.pieceIndex = pieceIndex;
     512    e.pieceIndex = req->index;
     513    e.offset = req->offset;
     514    e.length = req->length;
    558515    publish( msgs, &e );
    559516}
     
    806763
    807764static int
    808 requestIsValid( const tr_peermsgs *         peer,
    809                 const struct peer_request * req )
    810 {
    811     return reqIsValid( peer, req->index, req->offset, req->length );
    812 }
    813 
    814 static void
    815 tr_peerMsgsCancel( tr_peermsgs * msgs,
    816                    uint32_t      pieceIndex )
    817 {
    818     uint16_t              i;
    819     struct request_list   tmp = REQUEST_LIST_INIT;
    820     struct request_list * src;
    821 
    822     src = &msgs->clientWillAskFor;
    823     for( i = 0; i < src->count; ++i )
    824         if( src->requests[i].index != pieceIndex )
    825             reqListAppend( &tmp, src->requests + i );
    826 
    827     /* swap */
    828     reqListClear( &msgs->clientWillAskFor );
    829     msgs->clientWillAskFor = tmp;
    830     tmp = REQUEST_LIST_INIT;
    831 
    832     src = &msgs->clientAskedFor;
    833     for( i = 0; i < src->count; ++i )
    834         if( src->requests[i].index == pieceIndex )
    835             protocolSendCancel( msgs, src->requests + i );
    836         else
    837             reqListAppend( &tmp, src->requests + i );
    838 
    839     /* swap */
    840     reqListClear( &msgs->clientAskedFor );
    841     msgs->clientAskedFor = tmp;
    842     tmp = REQUEST_LIST_INIT;
    843 
    844     fireCancelledReq( msgs, pieceIndex );
     765requestIsValid( const tr_peermsgs * msgs, const struct peer_request * req )
     766{
     767    return reqIsValid( msgs, req->index, req->offset, req->length );
    845768}
    846769
     
    859782        const struct peer_request * req = &tmp.requests[i];
    860783        if( req->time_requested < oldestAllowed )
    861             tr_peerMsgsCancel( msgs, req->index );
     784            tr_peerMsgsCancel( msgs, req->index, req->offset, req->length );
    862785    }
    863786    reqListClear( &tmp );
     
    870793        const struct peer_request * req = &tmp.requests[i];
    871794        if( req->time_requested < oldestAllowed )
    872             tr_peerMsgsCancel( msgs, req->index );
     795            tr_peerMsgsCancel( msgs, req->index, req->offset, req->length );
    873796    }
    874797    reqListClear( &tmp );
     
    926849{
    927850    const int req_max = msgs->maxActiveRequests;
    928 
    929851    return msgs->clientWillAskFor.count >= req_max;
    930852}
     
    932854tr_addreq_t
    933855tr_peerMsgsAddRequest( tr_peermsgs *    msgs,
    934                        tr_piece_index_t piece )
     856                       uint32_t         index,
     857                       uint32_t         offset,
     858                       uint32_t         length )
    935859{
    936860    struct peer_request req;
     
    938862    assert( msgs );
    939863    assert( msgs->torrent );
    940     assert( piece < msgs->torrent->info.pieceCount );
     864    assert( reqIsValid( msgs, index, offset, length ) );
    941865
    942866    /**
     
    952876
    953877    /* peer doesn't have this piece */
    954     if( !tr_bitfieldHas( msgs->info->have, piece ) )
     878    if( !tr_bitfieldHas( msgs->info->have, index ) )
    955879        return TR_ADDREQ_MISSING;
    956880
    957881    /* peer's queue is full */
    958     if( requestQueueIsFull( msgs ) )
    959     {
     882    if( requestQueueIsFull( msgs ) ) {
    960883        dbgmsg( msgs, "declining request because we're full" );
    961884        return TR_ADDREQ_FULL;
     
    963886
    964887    /* have we already asked for this piece? */
    965     if( reqListHasPiece( &msgs->clientAskedFor, piece )
    966       || reqListHasPiece( &msgs->clientWillAskFor, piece ) )
    967     {
     888    req.index = index;
     889    req.offset = offset;
     890    req.length = length;
     891    if( reqListFind( &msgs->clientAskedFor, &req ) != -1 ) {
     892        dbgmsg( msgs, "declining because it's a duplicate" );
     893        return TR_ADDREQ_DUPLICATE;
     894    }
     895    if( reqListFind( &msgs->clientWillAskFor, &req ) != -1 ) {
    968896        dbgmsg( msgs, "declining because it's a duplicate" );
    969897        return TR_ADDREQ_DUPLICATE;
     
    974902    **/
    975903
    976     dbgmsg( msgs, "added req for piece %lu", (unsigned long)piece );
     904    dbgmsg( msgs, "added req for piece %lu", (unsigned long)index );
    977905    req.time_requested = time( NULL );
    978     reqListAppendPiece( msgs->torrent, &msgs->clientWillAskFor, piece );
     906    reqListAppend( &msgs->clientWillAskFor, &req );
    979907    return TR_ADDREQ_OK;
    980908}
     
    990918    msgs->clientWillAskFor = REQUEST_LIST_INIT;
    991919
    992     for( i = 0; i < a.count; ++i )
    993         fireCancelledReq( msgs, a.requests[i].index );
    994 
    995     for( i = 0; i < b.count; ++i )
    996     {
    997         fireCancelledReq( msgs, b.requests[i].index );
     920    for( i=0; i<a.count; ++i )
     921        fireCancelledReq( msgs, &a.requests[i] );
     922
     923    for( i = 0; i < b.count; ++i ) {
     924        fireCancelledReq( msgs, &b.requests[i] );
    998925        protocolSendCancel( msgs, &b.requests[i] );
    999926    }
     
    1001928    reqListClear( &a );
    1002929    reqListClear( &b );
     930}
     931
     932void
     933tr_peerMsgsCancel( tr_peermsgs * msgs,
     934                   uint32_t      pieceIndex,
     935                   uint32_t      offset,
     936                   uint32_t      length )
     937{
     938    struct peer_request req;
     939
     940    assert( msgs != NULL );
     941    assert( length > 0 );
     942
     943    /* have we asked the peer for this piece? */
     944    req.index = pieceIndex;
     945    req.offset = offset;
     946    req.length = length;
     947
     948    /* if it's only in the queue and hasn't been sent yet, free it */
     949    if( !reqListRemove( &msgs->clientWillAskFor, &req ) )
     950        fireCancelledReq( msgs, &req );
     951
     952    /* if it's already been sent, send a cancel message too */
     953    if( !reqListRemove( &msgs->clientAskedFor, &req ) ) {
     954        protocolSendCancel( msgs, &req );
     955        fireCancelledReq( msgs, &req );
     956    }
    1003957}
    1004958
  • trunk/libtransmission/peer-msgs.h

    r6795 r6882  
    3939void         tr_peerMsgsPulse( tr_peermsgs * msgs );
    4040
    41 #if 0
    4241void         tr_peerMsgsCancel( tr_peermsgs * msgs,
    4342                                uint32_t      pieceIndex,
     
    4544                                uint32_t      length );
    4645
    47 #endif
    4846
    4947void         tr_peerMsgsFree( tr_peermsgs* );
    5048
    51 tr_addreq_t  tr_peerMsgsAddRequest( tr_peermsgs *    peer,
    52                                     tr_piece_index_t piece );
     49tr_addreq_t  tr_peerMsgsAddRequest( tr_peermsgs * peer,
     50                                    uint32_t      pieceIndex,
     51                                    uint32_t      offset,
     52                                    uint32_t      length );
    5353
    5454void         tr_peerMsgsUnsubscribe( tr_peermsgs *    peer,
  • trunk/libtransmission/webseed.c

    r6832 r6882  
    2525#include "webseed.h"
    2626
    27 #define MAX_QUEUE_SIZE 4
    28 
    2927struct tr_webseed
    3028{
     29    unsigned int        busy : 1;
    3130    unsigned int        dead : 1;
    3231
     
    3736    void *              callback_userdata;
    3837
    39     uint64_t            bytesSaved;
    40 
    41     tr_piece_index_t    queue[MAX_QUEUE_SIZE];
    42     int                 queueSize;
     38    tr_piece_index_t    pieceIndex;
     39    uint32_t            pieceOffset;
     40    uint32_t            byteCount;
    4341
    4442    tr_ratecontrol *    rateDown;
     
    222220        /* FIXME */
    223221    }
    224     else if( w->dead )
    225     {
    226         tr_webseedFree( w );
    227     }
    228222    else
    229223    {
    230         const tr_piece_index_t piece = w->queue[0];
    231         tr_block_index_t       block;
    232         size_t                 len;
    233 
    234224        evbuffer_add( w->content, response, response_byte_count );
    235 
    236         fireClientGotData( w, response_byte_count );
    237 
    238         block = _tr_block( w->torrent, piece, w->bytesSaved );
    239         len = tr_torBlockCountBytes( w->torrent, block );
    240 
    241         while( EVBUFFER_LENGTH( w->content ) >= len )
     225        if( !w->dead )
    242226        {
    243 /*fprintf( stderr, "saving piece index %lu, offset %lu, len %lu\n", (unsigned
    244   long)piece, (unsigned long)w->bytesSaved, (unsigned long)len );*/
    245             /* save one block */
    246             tr_ioWrite( w->torrent, piece, w->bytesSaved, len,
    247                        EVBUFFER_DATA( w->content ) );
    248             evbuffer_drain( w->content, len );
    249             tr_rcTransferred( w->rateDown, len );
    250             fireClientGotBlock( w, piece, w->bytesSaved, len );
    251             w->bytesSaved += len;
    252 
    253             /* march to the next one */
    254             ++block;
    255             len = tr_torBlockCountBytes( w->torrent, block );
    256         }
    257 
    258         if( w->bytesSaved < tr_torPieceCountBytes( w->torrent, piece ) )
     227            fireClientGotData( w, response_byte_count );
     228            tr_rcTransferred( w->rateDown, response_byte_count );
     229        }
     230
     231        if( EVBUFFER_LENGTH( w->content ) < w->byteCount )
    259232            requestNextChunk( w );
    260         else
    261         {
    262             w->bytesSaved = 0;
     233        else {
     234            tr_ioWrite( w->torrent, w->pieceIndex, w->pieceOffset, w->byteCount, EVBUFFER_DATA(w->content) );
    263235            evbuffer_drain( w->content, EVBUFFER_LENGTH( w->content ) );
    264 /*fprintf( stderr, "w->callback_userdata is %p\n", w->callback_userdata );*/
    265             memmove( w->queue, w->queue + 1, sizeof( tr_piece_index_t ) *
    266                     ( MAX_QUEUE_SIZE - 1 ) );
    267 /*fprintf( stderr, "w->callback_userdata is %p\n", w->callback_userdata );*/
    268             if( --w->queueSize )
    269                 requestNextChunk( w );
    270             if( w->queueSize < ( MAX_QUEUE_SIZE / 2 ) )
     236            w->busy = 0;
     237            if( w->dead )
     238                tr_webseedFree( w );
     239            else  {
     240                fireClientGotBlock( w, w->pieceIndex, w->pieceOffset, w->byteCount );
    271241                fireNeedReq( w );
     242            }
    272243        }
    273244    }
     
    277248requestNextChunk( tr_webseed * w )
    278249{
    279     const tr_info *        inf = tr_torrentInfo( w->torrent );
    280     const uint32_t         have = w->bytesSaved + EVBUFFER_LENGTH(
    281         w->content );
    282     const tr_piece_index_t piece = w->queue[0];
    283     const uint32_t         left =
    284         tr_torPieceCountBytes( w->torrent, piece ) - have;
    285     const uint32_t         pieceOffset = have;
    286     tr_file_index_t        fileIndex;
    287     uint64_t               fileOffset;
    288     uint32_t               thisPass;
    289     char *                 url;
    290     char *                 range;
    291 
    292     tr_ioFindFileLocation( w->torrent, piece, pieceOffset,
     250    const tr_info * inf = tr_torrentInfo( w->torrent );
     251    const uint32_t have = EVBUFFER_LENGTH( w->content );
     252    const uint32_t left = w->byteCount - have;
     253    const uint32_t pieceOffset = w->pieceOffset + have;
     254    tr_file_index_t fileIndex;
     255    uint64_t fileOffset;
     256    uint32_t thisPass;
     257    char * url;
     258    char * range;
     259
     260    tr_ioFindFileLocation( w->torrent, w->pieceIndex, pieceOffset,
    293261                           &fileIndex, &fileOffset );
    294262    thisPass = MIN( left, inf->files[fileIndex].length - fileOffset );
    295263
    296264    url = makeURL( w, &inf->files[fileIndex] );
    297     range = tr_strdup_printf( "%" PRIu64 "-%" PRIu64, fileOffset,
    298                               fileOffset + thisPass - 1 );
    299 /*fprintf( stderr, "range is [%s] ... we want %lu total, we have %lu, so %lu are
    300   left, and we're asking for %lu this time\n", range, (unsigned
    301   long)tr_torPieceCountBytes(w->torrent,piece), (unsigned long)have, (unsigned
    302   long)left, (unsigned long)thisPass );*/
     265//fprintf( stderr, "url is [%s]\n", url );
     266    range = tr_strdup_printf( "%"PRIu64"-%"PRIu64, fileOffset, fileOffset + thisPass - 1 );
     267//fprintf( stderr, "range is [%s] ... we want %lu total, we have %lu, so %lu are left, and we're asking for %lu this time\n", range, (unsigned long)w->byteCount, (unsigned long)have, (unsigned long)left, (unsigned long)thisPass );
    303268    tr_webRun( w->torrent->session, url, range, webResponseFunc, w );
    304269    tr_free( range );
     
    307272
    308273tr_addreq_t
    309 tr_webseedAddRequest( tr_webseed *     w,
    310                       tr_piece_index_t piece )
     274tr_webseedAddRequest( tr_webseed  * w,
     275                      uint32_t      pieceIndex,
     276                      uint32_t      pieceOffset,
     277                      uint32_t      byteCount )
    311278{
    312279    int ret;
    313280
    314     if( w->dead || w->queueSize >= MAX_QUEUE_SIZE )
     281    if( w->busy || w->dead )
    315282    {
    316283        ret = TR_ADDREQ_FULL;
     
    318285    else
    319286    {
    320         int wasEmpty = w->queueSize == 0;
    321         w->queue[w->queueSize++] = piece;
    322         if( wasEmpty )
    323             requestNextChunk( w );
     287        w->busy = 1;
     288        w->pieceIndex = pieceIndex;
     289        w->pieceOffset = pieceOffset;
     290        w->byteCount = byteCount;
     291        evbuffer_drain( w->content, EVBUFFER_LENGTH( w->content ) );
     292        requestNextChunk( w );
    324293        ret = TR_ADDREQ_OK;
    325294    }
     
    331300tr_webseedIsActive( const tr_webseed * w )
    332301{
    333     return w->queueSize > 0;
     302    return w->busy != 0;
    334303}
    335304
     
    371340    if( w )
    372341    {
    373         if( w->queueSize > 0 )
     342        if( w->busy )
    374343        {
    375344            w->dead = 1;
     
    384353    }
    385354}
    386 
  • trunk/libtransmission/webseed.h

    r6795 r6882  
    2626
    2727tr_addreq_t tr_webseedAddRequest( tr_webseed *     w,
    28                                   tr_piece_index_t piece );
     28                                  uint32_t         index,
     29                                  uint32_t         offset,
     30                                  uint32_t         length );
    2931
    3032/** @return true if a request is being processed, or false if idle */
Note: See TracChangeset for help on using the changeset viewer.