Changeset 6882
- Timestamp:
- Oct 11, 2008, 4:07:50 AM (13 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/peer-mgr.c
r6878 r6882 115 115 tr_torrent * tor; 116 116 tr_peer * optimistic; /* the optimistic peer, or NULL if none */ 117 tr_bitfield * requested Pieces;117 tr_bitfield * requestedBlocks; 118 118 119 119 unsigned int isRunning : 1; … … 406 406 tr_timerFree( &t->refillTimer ); 407 407 408 tr_bitfieldFree( t->requested Pieces );408 tr_bitfieldFree( t->requestedBlocks ); 409 409 tr_ptrArrayFree( t->webseeds, (PtrArrayForeachFunc)tr_webseedFree ); 410 410 tr_ptrArrayFree( t->pool, (PtrArrayForeachFunc)tr_free ); … … 433 433 t->webseeds = tr_ptrArrayNew( ); 434 434 t->outgoingHandshakes = tr_ptrArrayNew( ); 435 t->requested Pieces = tr_bitfieldNew( tor->info.pieceCount );435 t->requestedBlocks = tr_bitfieldNew( tor->blockCount ); 436 436 memcpy( t->hash, tor->info.hash, SHA_DIGEST_LENGTH ); 437 437 … … 594 594 struct tr_refill_piece 595 595 { 596 int missingBlockCount; 596 597 tr_priority_t priority; 597 598 int random; … … 606 607 const struct tr_refill_piece * a = aIn; 607 608 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; 608 613 609 614 /* if one piece has a higher priority, it goes first */ … … 672 677 setme->peerCount = 0; 673 678 setme->random = tr_cryptoWeakRandInt( INT_MAX ); 679 setme->missingBlockCount = tr_cpMissingBlocksInPiece( tor->completion, piece ); 674 680 675 681 for( k = 0; k < peerCount; ++k ) … … 697 703 } 698 704 705 static uint64_t* 706 getPreferredBlocks( 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 699 793 static tr_peer** 700 794 getPeersUploadingToClient( Torrent * t, … … 733 827 Torrent * t = vtorrent; 734 828 tr_torrent * tor = t->tor; 829 tr_block_index_t i; 735 830 int peerCount; 736 831 int webseedCount; 737 832 tr_peer ** peers; 738 833 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; 742 836 743 837 if( !t->isRunning ) … … 749 843 tordbg( t, "Refilling Request Buffers..." ); 750 844 751 pieces = getPreferredPieces( t, &pieceCount );845 blocks = getPreferredBlocks( t, &blockCount ); 752 846 peers = getPeersUploadingToClient( t, &peerCount ); 753 847 webseedCount = tr_ptrArraySize( t->webseeds ); … … 756 850 sizeof( tr_webseed* ) ); 757 851 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 */ 767 868 for( j = 0; !handled && j < peerCount; ) 768 869 { 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 ); 771 871 switch( val ) 772 872 { … … 782 882 783 883 case TR_ADDREQ_OK: 784 tr_bitfieldAdd( t->requested Pieces, piece);884 tr_bitfieldAdd( t->requestedBlocks, block ); 785 885 handled = TRUE; 786 886 break; … … 795 895 for( j = 0; !handled && j < webseedCount; ) 796 896 { 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 ); 799 898 switch( val ) 800 899 { … … 804 903 805 904 case TR_ADDREQ_OK: 806 tr_bitfieldAdd( t->requested Pieces, piece);905 tr_bitfieldAdd( t->requestedBlocks, block ); 807 906 handled = TRUE; 808 907 break; … … 818 917 tr_free( webseeds ); 819 918 tr_free( peers ); 820 tr_free( pieces );919 tr_free( blocks ); 821 920 822 921 t->refillTimer = NULL; 823 922 torrentUnlock( t ); 824 923 return FALSE; 924 } 925 926 static void 927 broadcastGotBlock( 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 ); 825 938 } 826 939 … … 881 994 882 995 case TR_PEER_CANCEL: 883 tr_bitfieldRem( t->requested Pieces, e->pieceIndex);996 tr_bitfieldRem( t->requestedBlocks, _tr_block( t->tor, e->pieceIndex, e->offset ) ); 884 997 break; 885 998 … … 914 1027 tor->downloadedCur += e->length; 915 1028 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 ); 920 1031 atom->piece_data_time = time( NULL ); 921 1032 } … … 956 1067 957 1068 tr_cpBlockAdd( tor->completion, block ); 1069 1070 broadcastGotBlock( t, e->pieceIndex, e->offset, e->length ); 958 1071 959 1072 if( tr_cpPieceIsComplete( tor->completion, e->pieceIndex ) ) -
trunk/libtransmission/peer-msgs.c
r6880 r6882 199 199 } 200 200 201 static void202 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 231 201 static int 232 202 reqListPop( struct request_list * list, … … 244 214 245 215 return success; 246 }247 248 static int249 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;259 216 } 260 217 … … 549 506 550 507 static void 551 fireCancelledReq( tr_peermsgs * msgs, 552 const tr_piece_index_t pieceIndex ) 508 fireCancelledReq( tr_peermsgs * msgs, const struct peer_request * req ) 553 509 { 554 510 tr_peer_event e = blankEvent; 555 556 511 e.eventType = TR_PEER_CANCEL; 557 e.pieceIndex = pieceIndex; 512 e.pieceIndex = req->index; 513 e.offset = req->offset; 514 e.length = req->length; 558 515 publish( msgs, &e ); 559 516 } … … 806 763 807 764 static 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 ); 765 requestIsValid( const tr_peermsgs * msgs, const struct peer_request * req ) 766 { 767 return reqIsValid( msgs, req->index, req->offset, req->length ); 845 768 } 846 769 … … 859 782 const struct peer_request * req = &tmp.requests[i]; 860 783 if( req->time_requested < oldestAllowed ) 861 tr_peerMsgsCancel( msgs, req->index );784 tr_peerMsgsCancel( msgs, req->index, req->offset, req->length ); 862 785 } 863 786 reqListClear( &tmp ); … … 870 793 const struct peer_request * req = &tmp.requests[i]; 871 794 if( req->time_requested < oldestAllowed ) 872 tr_peerMsgsCancel( msgs, req->index );795 tr_peerMsgsCancel( msgs, req->index, req->offset, req->length ); 873 796 } 874 797 reqListClear( &tmp ); … … 926 849 { 927 850 const int req_max = msgs->maxActiveRequests; 928 929 851 return msgs->clientWillAskFor.count >= req_max; 930 852 } … … 932 854 tr_addreq_t 933 855 tr_peerMsgsAddRequest( tr_peermsgs * msgs, 934 tr_piece_index_t piece ) 856 uint32_t index, 857 uint32_t offset, 858 uint32_t length ) 935 859 { 936 860 struct peer_request req; … … 938 862 assert( msgs ); 939 863 assert( msgs->torrent ); 940 assert( piece < msgs->torrent->info.pieceCount);864 assert( reqIsValid( msgs, index, offset, length ) ); 941 865 942 866 /** … … 952 876 953 877 /* peer doesn't have this piece */ 954 if( !tr_bitfieldHas( msgs->info->have, piece) )878 if( !tr_bitfieldHas( msgs->info->have, index ) ) 955 879 return TR_ADDREQ_MISSING; 956 880 957 881 /* peer's queue is full */ 958 if( requestQueueIsFull( msgs ) ) 959 { 882 if( requestQueueIsFull( msgs ) ) { 960 883 dbgmsg( msgs, "declining request because we're full" ); 961 884 return TR_ADDREQ_FULL; … … 963 886 964 887 /* 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 ) { 968 896 dbgmsg( msgs, "declining because it's a duplicate" ); 969 897 return TR_ADDREQ_DUPLICATE; … … 974 902 **/ 975 903 976 dbgmsg( msgs, "added req for piece %lu", (unsigned long) piece);904 dbgmsg( msgs, "added req for piece %lu", (unsigned long)index ); 977 905 req.time_requested = time( NULL ); 978 reqListAppend Piece( msgs->torrent, &msgs->clientWillAskFor, piece);906 reqListAppend( &msgs->clientWillAskFor, &req ); 979 907 return TR_ADDREQ_OK; 980 908 } … … 990 918 msgs->clientWillAskFor = REQUEST_LIST_INIT; 991 919 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] ); 998 925 protocolSendCancel( msgs, &b.requests[i] ); 999 926 } … … 1001 928 reqListClear( &a ); 1002 929 reqListClear( &b ); 930 } 931 932 void 933 tr_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 } 1003 957 } 1004 958 -
trunk/libtransmission/peer-msgs.h
r6795 r6882 39 39 void tr_peerMsgsPulse( tr_peermsgs * msgs ); 40 40 41 #if 042 41 void tr_peerMsgsCancel( tr_peermsgs * msgs, 43 42 uint32_t pieceIndex, … … 45 44 uint32_t length ); 46 45 47 #endif48 46 49 47 void tr_peerMsgsFree( tr_peermsgs* ); 50 48 51 tr_addreq_t tr_peerMsgsAddRequest( tr_peermsgs * peer, 52 tr_piece_index_t piece ); 49 tr_addreq_t tr_peerMsgsAddRequest( tr_peermsgs * peer, 50 uint32_t pieceIndex, 51 uint32_t offset, 52 uint32_t length ); 53 53 54 54 void tr_peerMsgsUnsubscribe( tr_peermsgs * peer, -
trunk/libtransmission/webseed.c
r6832 r6882 25 25 #include "webseed.h" 26 26 27 #define MAX_QUEUE_SIZE 428 29 27 struct tr_webseed 30 28 { 29 unsigned int busy : 1; 31 30 unsigned int dead : 1; 32 31 … … 37 36 void * callback_userdata; 38 37 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; 43 41 44 42 tr_ratecontrol * rateDown; … … 222 220 /* FIXME */ 223 221 } 224 else if( w->dead )225 {226 tr_webseedFree( w );227 }228 222 else 229 223 { 230 const tr_piece_index_t piece = w->queue[0];231 tr_block_index_t block;232 size_t len;233 234 224 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 ) 242 226 { 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 ) 259 232 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) ); 263 235 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 ); 271 241 fireNeedReq( w ); 242 } 272 243 } 273 244 } … … 277 248 requestNextChunk( tr_webseed * w ) 278 249 { 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, 293 261 &fileIndex, &fileOffset ); 294 262 thisPass = MIN( left, inf->files[fileIndex].length - fileOffset ); 295 263 296 264 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 ); 303 268 tr_webRun( w->torrent->session, url, range, webResponseFunc, w ); 304 269 tr_free( range ); … … 307 272 308 273 tr_addreq_t 309 tr_webseedAddRequest( tr_webseed * w, 310 tr_piece_index_t piece ) 274 tr_webseedAddRequest( tr_webseed * w, 275 uint32_t pieceIndex, 276 uint32_t pieceOffset, 277 uint32_t byteCount ) 311 278 { 312 279 int ret; 313 280 314 if( w-> dead || w->queueSize >= MAX_QUEUE_SIZE)281 if( w->busy || w->dead ) 315 282 { 316 283 ret = TR_ADDREQ_FULL; … … 318 285 else 319 286 { 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 ); 324 293 ret = TR_ADDREQ_OK; 325 294 } … … 331 300 tr_webseedIsActive( const tr_webseed * w ) 332 301 { 333 return w-> queueSize >0;302 return w->busy != 0; 334 303 } 335 304 … … 371 340 if( w ) 372 341 { 373 if( w-> queueSize > 0)342 if( w->busy ) 374 343 { 375 344 w->dead = 1; … … 384 353 } 385 354 } 386 -
trunk/libtransmission/webseed.h
r6795 r6882 26 26 27 27 tr_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 ); 29 31 30 32 /** @return true if a request is being processed, or false if idle */
Note: See TracChangeset
for help on using the changeset viewer.