Changeset 5172
- Timestamp:
- Feb 29, 2008, 3:41:50 AM (15 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/ipcparse.c
r5143 r5172 309 309 { 310 310 tr_benc pk; 311 uint8_t * ret ;312 313 if( NULL ==ipc_initval( info, id, tag, &pk, TYPE_STR ) )314 return NULL;315 316 ret = ipc_mkval( &pk, len);317 SAFEBENCFREE( &pk );311 uint8_t * ret = NULL; 312 313 if( ipc_initval( info, id, tag, &pk, TYPE_STR ) ) 314 { 315 ret = ipc_mkval( &pk, len ); 316 SAFEBENCFREE( &pk ); 317 } 318 318 319 319 return ret; … … 325 325 { 326 326 tr_benc pk, * val; 327 uint8_t * ret; 328 329 val = ipc_initval( info, id, tag, &pk, TYPE_INT ); 330 if( !val ) 331 return NULL; 332 333 val->val.i = num; 334 ret = ipc_mkval( &pk, len ); 335 SAFEBENCFREE( &pk ); 327 uint8_t * ret = NULL; 328 329 if(( val = ipc_initval( info, id, tag, &pk, TYPE_INT ))) 330 { 331 val->val.i = num; 332 ret = ipc_mkval( &pk, len ); 333 SAFEBENCFREE( &pk ); 334 } 336 335 337 336 return ret; … … 343 342 { 344 343 tr_benc pk, * val; 345 uint8_t * ret; 346 347 val = ipc_initval( info, id, tag, &pk, TYPE_STR ); 348 if( !val ) 349 return NULL; 350 351 tr_bencInitStr( val, str, -1, 1 ); 352 ret = ipc_mkval( &pk, len ); 353 SAFEBENCFREE( &pk ); 344 uint8_t * ret = NULL; 345 346 if(( val = ipc_initval( info, id, tag, &pk, TYPE_STR ))) 347 { 348 tr_bencInitStr( val, str, -1, 1 ); 349 ret = ipc_mkval( &pk, len ); 350 SAFEBENCFREE( &pk ); 351 } 354 352 355 353 return ret; -
trunk/libtransmission/peer-msgs.c
r5127 r5172 24 24 #include "completion.h" 25 25 #include "inout.h" 26 #include "list.h"27 26 #include "peer-io.h" 28 27 #include "peer-mgr.h" … … 71 70 RATE_PULSE_INTERVAL = (250), /* msec between calls to ratePulse() */ 72 71 72 MAX_QUEUE_SIZE = (100), 73 73 74 MAX_OUTBUF_SIZE = (1024), 74 75 … … 80 81 81 82 SENT_REQUEST_TTL_SECS = 90 82 83 83 }; 84 84 … … 111 111 } 112 112 113 struct request_list 114 { 115 uint16_t count; 116 uint16_t max; 117 struct peer_request * requests; 118 }; 119 120 static const struct request_list REQUEST_LIST_INIT = { 0, 0, NULL }; 121 122 static void 123 reqListReserve( struct request_list * list, uint16_t max ) 124 { 125 if( list->max < max ) 126 { 127 list->max = max; 128 list->requests = tr_renew( struct peer_request, list->requests, list->max ); 129 } 130 } 131 132 static void 133 reqListClear( struct request_list * list ) 134 { 135 tr_free( list->requests ); 136 *list = REQUEST_LIST_INIT; 137 } 138 139 static void 140 reqListRemoveOne( struct request_list * list, int i ) 141 { 142 assert( 0<=i && i<list->count ); 143 144 memmove( &list->requests[i], 145 &list->requests[i+1], 146 sizeof( struct peer_request ) * ( --list->count - i ) ); 147 } 148 149 static void 150 reqListAppend( struct request_list * list, const struct peer_request * req ) 151 { 152 if( ++list->count >= list->max ) 153 reqListReserve( list, list->max + 8 ); 154 155 list->requests[list->count-1] = *req; 156 } 157 158 static tr_errno 159 reqListPop( struct request_list * list, struct peer_request * setme ) 160 { 161 tr_errno err; 162 163 if( !list->count ) 164 err = TR_ERROR; 165 else { 166 *setme = list->requests[0]; 167 reqListRemoveOne( list, 0 ); 168 err = TR_OK; 169 } 170 171 return err; 172 } 173 174 static int 175 reqListFind( struct request_list * list, const struct peer_request * key ) 176 { 177 uint16_t i; 178 for( i=0; i<list->count; ++i ) 179 if( !compareRequest( key, list->requests+i ) ) 180 return i; 181 return -1; 182 } 183 184 static tr_errno 185 reqListRemove( struct request_list * list, const struct peer_request * key ) 186 { 187 tr_errno err; 188 const int i = reqListFind( list, key ); 189 190 if( i < 0 ) 191 err = TR_ERROR; 192 else { 193 err = TR_OK; 194 reqListRemoveOne( list, i ); 195 } 196 197 return err; 198 } 199 200 static void 201 reqListPrune( struct request_list * list, 202 struct request_list * pruned, 203 time_t cutoff ) 204 { 205 int i, k=0, p=0; 206 struct peer_request keep[MAX_QUEUE_SIZE]; 207 struct peer_request prune[MAX_QUEUE_SIZE]; 208 209 for( i=0; i<list->count; ++i ) { 210 const struct peer_request * req = list->requests + i; 211 if( req->time_requested > cutoff ) 212 keep[k++] = *req; 213 else 214 prune[p++] = *req; 215 } 216 217 memcpy( list->requests, keep, sizeof(struct peer_request) * k ); 218 list->count = k; 219 220 reqListReserve( pruned, pruned->count + p ); 221 memcpy( pruned->requests + pruned->count, prune, sizeof(struct peer_request) * p ); 222 pruned->count += p; 223 } 224 113 225 /* this is raw, unchanged data from the peer regarding 114 226 * the current message that it's sending us. */ … … 133 245 struct evbuffer * outBlock; /* buffer of all the current piece message */ 134 246 struct evbuffer * outMessages; /* buffer of all the non-piece messages */ 135 tr_list *peerAskedFor;136 tr_list *peerAskedForFast;137 tr_list *clientAskedFor;138 tr_list *clientWillAskFor;247 struct request_list peerAskedFor; 248 struct request_list peerAskedForFast; 249 struct request_list clientAskedFor; 250 struct request_list clientWillAskFor; 139 251 140 252 tr_timer * rateTimer; … … 414 526 cancelAllRequestsToClientExceptFast( tr_peermsgs * msgs ) 415 527 { 416 tr_list_free( &msgs->peerAskedFor, tr_free);528 reqListClear( &msgs->peerAskedFor ); 417 529 } 418 530 … … 584 696 expireOldRequests( tr_peermsgs * msgs ) 585 697 { 586 tr_list * l; 587 tr_list * prune = NULL; 698 int i; 588 699 const time_t now = time( NULL ); 589 590 /* find queued requests that are too old 591 "time_requested" here is when the request was queued */ 592 for( l=msgs->clientWillAskFor; l!=NULL; l=l->next ) { 593 struct peer_request * req = l->data; 594 if( req->time_requested + QUEUED_REQUEST_TTL_SECS < now ) 595 tr_list_prepend( &prune, req ); 596 } 597 598 /* find sent requests that are too old 599 "time_requested" here is when the request was sent */ 600 for( l=msgs->clientAskedFor; l!=NULL; l=l->next ) { 601 struct peer_request * req = l->data; 602 if( req->time_requested + SENT_REQUEST_TTL_SECS < now ) 603 tr_list_prepend( &prune, req ); 604 } 700 const time_t queued_cutoff = now - QUEUED_REQUEST_TTL_SECS; 701 const time_t sent_cutoff = now - SENT_REQUEST_TTL_SECS; 702 struct request_list pruned = REQUEST_LIST_INIT; 703 704 reqListPrune( &msgs->clientWillAskFor, &pruned, queued_cutoff ); 705 reqListPrune( &msgs->clientAskedFor, &pruned, sent_cutoff ); 605 706 606 707 /* expire the old requests */ 607 for( l=prune; l!=NULL; l=l->next) {608 struct peer_request * req = l->data;708 for( i=0; i<pruned.count; ++i ) { 709 const struct peer_request * req = &pruned.requests[i]; 609 710 tr_peerMsgsCancel( msgs, req->index, req->offset, req->length ); 610 711 } 611 712 612 713 /* cleanup */ 613 tr_list_free( &prune, NULL);714 reqListClear( &pruned ); 614 715 } 615 716 … … 617 718 pumpRequestQueue( tr_peermsgs * msgs ) 618 719 { 720 struct peer_request req; 619 721 const int max = msgs->maxActiveRequests; 620 722 const int min = msgs->minActiveRequests; 621 int count = tr_list_size( msgs->clientAskedFor ); 723 const time_t now = time( NULL ); 724 int count = msgs->clientAskedFor.count; 622 725 int sent = 0; 623 726 … … 627 730 return; 628 731 629 while( ( count < max ) && ( msgs->clientWillAskFor != NULL ) ) 630 { 631 struct peer_request * r = tr_list_pop_front( &msgs->clientWillAskFor ); 632 assert( requestIsValid( msgs, r ) ); 633 assert( tr_bitfieldHas( msgs->info->have, r->index ) ); 634 protocolSendRequest( msgs, r ); 635 r->time_requested = msgs->lastReqAddedAt = time( NULL ); 636 tr_list_append( &msgs->clientAskedFor, r ); 732 while( ( count < max ) && !reqListPop( &msgs->clientWillAskFor, &req ) ) 733 { 734 assert( requestIsValid( msgs, &req ) ); 735 assert( tr_bitfieldHas( msgs->info->have, req.index ) ); 736 737 protocolSendRequest( msgs, &req ); 738 req.time_requested = msgs->lastReqAddedAt = now; 739 reqListAppend( &msgs->clientAskedFor, &req ); 740 637 741 ++count; 638 742 ++sent; … … 642 746 dbgmsg( msgs, "pump sent %d requests, now have %d active and %d queued", 643 747 sent, 644 tr_list_size(msgs->clientAskedFor),645 tr_list_size(msgs->clientWillAskFor));748 msgs->clientAskedFor.count, 749 msgs->clientWillAskFor.count ); 646 750 647 751 if( count < max ) … … 659 763 { 660 764 const int req_max = msgs->maxActiveRequests; 661 struct peer_request tmp, *req;765 struct peer_request req; 662 766 663 767 assert( msgs != NULL ); … … 680 784 681 785 /* peer's queue is full */ 682 if( tr_list_size( msgs->clientWillAskFor )>= req_max ) {786 if( msgs->clientWillAskFor.count >= req_max ) { 683 787 dbgmsg( msgs, "declining request because we're full" ); 684 788 return TR_ADDREQ_FULL; … … 686 790 687 791 /* have we already asked for this piece? */ 688 tmp.index = index;689 tmp.offset = offset;690 tmp.length = length;691 if( tr_list_find( msgs->clientAskedFor, &tmp, compareRequest )) {792 req.index = index; 793 req.offset = offset; 794 req.length = length; 795 if( reqListFind( &msgs->clientAskedFor, &req ) != -1 ) { 692 796 dbgmsg( msgs, "declining because it's a duplicate" ); 693 797 return TR_ADDREQ_DUPLICATE; 694 798 } 695 if( tr_list_find( msgs->clientWillAskFor, &tmp, compareRequest )) {799 if( reqListFind( &msgs->clientWillAskFor, &req ) != -1 ) { 696 800 dbgmsg( msgs, "declining because it's a duplicate" ); 697 801 return TR_ADDREQ_DUPLICATE; … … 703 807 704 808 dbgmsg( msgs, "added req for piece %d, offset %d", (int)index, (int)offset ); 705 req = tr_new0( struct peer_request, 1 ); 706 *req = tmp; 707 req->time_requested = time( NULL ); 708 tr_list_append( &msgs->clientWillAskFor, req ); 809 req.time_requested = time( NULL ); 810 reqListAppend( &msgs->clientWillAskFor, &req ); 709 811 return TR_ADDREQ_OK; 710 812 } … … 713 815 cancelAllRequestsToPeer( tr_peermsgs * msgs ) 714 816 { 715 struct peer_request * req; 716 717 while(( req = tr_list_pop_front( &msgs->clientWillAskFor ) )) 718 { 719 fireCancelledReq( msgs, req ); 720 tr_free( req ); 721 } 722 723 while(( req = tr_list_pop_front( &msgs->clientAskedFor ) )) 724 { 725 fireCancelledReq( msgs, req ); 726 protocolSendCancel( msgs, req ); 727 tr_free( req ); 728 } 817 int i; 818 struct request_list a = msgs->clientWillAskFor; 819 struct request_list b = msgs->clientAskedFor; 820 821 msgs->clientAskedFor = REQUEST_LIST_INIT; 822 msgs->clientWillAskFor = REQUEST_LIST_INIT; 823 824 for( i=0; i<a.count; ++i ) 825 fireCancelledReq( msgs, &a.requests[i] ); 826 827 for( i=0; i<b.count; ++i ) { 828 fireCancelledReq( msgs, &b.requests[i] ); 829 protocolSendCancel( msgs, &b.requests[i] ); 830 } 831 832 reqListClear( &a ); 833 reqListClear( &b ); 729 834 } 730 835 … … 735 840 uint32_t length ) 736 841 { 737 struct peer_request *req, tmp;842 struct peer_request req; 738 843 739 844 assert( msgs != NULL ); … … 741 846 742 847 /* have we asked the peer for this piece? */ 743 tmp.index = pieceIndex;744 tmp.offset = offset;745 tmp.length = length;848 req.index = pieceIndex; 849 req.offset = offset; 850 req.length = length; 746 851 747 852 /* if it's only in the queue and hasn't been sent yet, free it */ 748 if(( req = tr_list_remove( &msgs->clientWillAskFor, &tmp, compareRequest ) )) 749 { 750 fireCancelledReq( msgs, req ); 751 tr_free( req ); 752 } 853 if( !reqListRemove( &msgs->clientWillAskFor, &req ) ) 854 fireCancelledReq( msgs, &req ); 753 855 754 856 /* if it's already been sent, send a cancel message too */ 755 if(( req = tr_list_remove( &msgs->clientAskedFor, &tmp, compareRequest ) )) 756 { 757 protocolSendCancel( msgs, req ); 758 fireCancelledReq( msgs, req ); 759 tr_free( req ); 857 if( !reqListRemove( &msgs->clientAskedFor, &req ) ) { 858 protocolSendCancel( msgs, &req ); 859 fireCancelledReq( msgs, &req ); 760 860 } 761 861 } … … 1032 1132 else /* YAY */ 1033 1133 { 1034 struct peer_request * tmp = tr_new( struct peer_request, 1 );1035 *tmp = *req;1036 1134 if( peerIsFast && pieceIsFast ) 1037 tr_list_append( &msgs->peerAskedForFast, tmp);1135 reqListAppend( &msgs->peerAskedForFast, req ); 1038 1136 else 1039 tr_list_append( &msgs->peerAskedFor, tmp);1137 reqListAppend( &msgs->peerAskedFor, req ); 1040 1138 } 1041 1139 } … … 1240 1338 tr_peerIoReadUint32( msgs->io, inbuf, &req.length ); 1241 1339 dbgmsg( msgs, "got a Cancel %u:%u->%u", req.index, req.offset, req.length ); 1242 tr_free( tr_list_remove( &msgs->peerAskedForFast, &req, compareRequest ));1243 tr_free( tr_list_remove( &msgs->peerAskedFor, &req, compareRequest ));1340 reqListRemove( &msgs->peerAskedForFast, &req ); 1341 reqListRemove( &msgs->peerAskedFor, &req ); 1244 1342 break; 1245 1343 } … … 1284 1382 tr_peerIoReadUint32( msgs->io, inbuf, &req.offset ); 1285 1383 tr_peerIoReadUint32( msgs->io, inbuf, &req.length ); 1286 tr_free( tr_list_remove( &msgs->clientAskedFor, &req, compareRequest ));1384 reqListRemove( &msgs->clientAskedFor, &req ); 1287 1385 break; 1288 1386 } … … 1391 1489 tr_torrent * tor = msgs->torrent; 1392 1490 const int block = _tr_block( tor, req->index, req->offset ); 1393 struct peer_request *myreq;1394 1491 1395 1492 assert( msgs != NULL ); … … 1410 1507 **/ 1411 1508 1412 myreq = tr_list_remove( &msgs->clientAskedFor, req, compareRequest );1413 if( myreq == NULL ){1509 if( reqListRemove( &msgs->clientAskedFor, req ) ) 1510 { 1414 1511 clientGotUnwantedBlock( msgs, req ); 1415 1512 dbgmsg( msgs, "we didn't ask for this message..." ); … … 1417 1514 } 1418 1515 1419 dbgmsg( msgs, "got block %u:%u->%u (turnaround time %d secs)",1420 myreq->index, myreq->offset, myreq->length,1421 (int)(time(NULL) - myreq->time_requested) );1422 1516 dbgmsg( msgs, "peer has %d more blocks we've asked for", 1423 tr_list_size(msgs->clientAskedFor)); 1424 1425 tr_free( myreq ); 1426 myreq = NULL; 1517 msgs->clientAskedFor.count ); 1427 1518 1428 1519 /** … … 1556 1647 msgs->info->rateToClient = tr_rcRate( msgs->info->rcToClient ); 1557 1648 msgs->info->rateToPeer = tr_rcRate( msgs->info->rcToPeer ); 1558 msgs->maxActiveRequests = MIN( 4 + (int)(msgs->info->rateToClient/4), 100);1649 msgs->maxActiveRequests = MIN( 4 + (int)(msgs->info->rateToClient/4), MAX_QUEUE_SIZE ); 1559 1650 msgs->minActiveRequests = msgs->maxActiveRequests / 3; 1560 1651 return TRUE; 1561 1652 } 1562 1653 1563 static struct peer_request* 1564 popNextRequest( tr_peermsgs * msgs ) 1565 { 1566 struct peer_request * ret; 1567 ret = tr_list_pop_front( &msgs->peerAskedForFast ); 1568 if( !ret ) 1569 ret = tr_list_pop_front( &msgs->peerAskedFor); 1570 return ret; 1654 static tr_errno 1655 popNextRequest( tr_peermsgs * msgs, struct peer_request * setme ) 1656 { 1657 if( !reqListPop( &msgs->peerAskedForFast, setme ) ) 1658 return 0; 1659 if( !reqListPop( &msgs->peerAskedFor, setme ) ) 1660 return 0; 1661 1662 return TR_ERROR; 1571 1663 } 1572 1664 … … 1576 1668 const time_t now = time( NULL ); 1577 1669 tr_peermsgs * msgs = vmsgs; 1578 struct peer_request * r;1579 1670 1580 1671 tr_peerIoTryRead( msgs->io ); … … 1607 1698 if( !msgs->sendingBlock ) 1608 1699 { 1700 struct peer_request req; 1701 1609 1702 if(( EVBUFFER_LENGTH( msgs->outMessages ) )) 1610 1703 { … … 1614 1707 } 1615 1708 else if( !EVBUFFER_LENGTH( msgs->outBlock ) 1616 && (( r = popNextRequest( msgs )))1617 && requestIsValid( msgs, r)1618 && tr_cpPieceIsComplete( msgs->torrent->completion, r ->index ) )1709 && !popNextRequest( msgs, &req ) 1710 && requestIsValid( msgs, &req ) 1711 && tr_cpPieceIsComplete( msgs->torrent->completion, req.index ) ) 1619 1712 { 1620 uint8_t * buf = tr_new( uint8_t, r ->length );1621 1622 if( !tr_ioRead( msgs->torrent, r ->index, r->offset, r->length, buf ) )1713 uint8_t * buf = tr_new( uint8_t, req.length ); 1714 1715 if( !tr_ioRead( msgs->torrent, req.index, req.offset, req.length, buf ) ) 1623 1716 { 1624 1717 tr_peerIo * io = msgs->io; 1625 1718 struct evbuffer * out = msgs->outBlock; 1626 1719 1627 dbgmsg( msgs, "sending block %u:%u->%u", r ->index, r->offset, r->length );1628 tr_peerIoWriteUint32( io, out, sizeof(uint8_t) + 2*sizeof(uint32_t) + r ->length );1720 dbgmsg( msgs, "sending block %u:%u->%u", req.index, req.offset, req.length ); 1721 tr_peerIoWriteUint32( io, out, sizeof(uint8_t) + 2*sizeof(uint32_t) + req.length ); 1629 1722 tr_peerIoWriteUint8 ( io, out, BT_PIECE ); 1630 tr_peerIoWriteUint32( io, out, r ->index );1631 tr_peerIoWriteUint32( io, out, r ->offset );1632 tr_peerIoWriteBytes ( io, out, buf, r ->length );1723 tr_peerIoWriteUint32( io, out, req.index ); 1724 tr_peerIoWriteUint32( io, out, req.offset ); 1725 tr_peerIoWriteBytes ( io, out, buf, req.length ); 1633 1726 msgs->sendingBlock = 1; 1634 1727 } 1635 1728 1636 1729 tr_free( buf ); 1637 tr_free( r );1638 1730 } 1639 1731 else if( ( now - msgs->clientSentAnythingAt ) > KEEPALIVE_INTERVAL_SECS ) … … 1851 1943 m->outBlock = evbuffer_new( ); 1852 1944 m->peerAllowedPieces = NULL; 1945 m->peerAskedFor = REQUEST_LIST_INIT; 1946 m->peerAskedForFast = REQUEST_LIST_INIT; 1947 m->clientAskedFor = REQUEST_LIST_INIT; 1948 m->clientWillAskFor = REQUEST_LIST_INIT; 1853 1949 m->clientAllowedPieces = tr_bitfieldNew( m->torrent->info.pieceCount ); 1854 1950 m->clientSuggestedPieces = tr_bitfieldNew( m->torrent->info.pieceCount ); … … 1889 1985 tr_timerFree( &msgs->pexTimer ); 1890 1986 tr_publisherFree( &msgs->publisher ); 1891 tr_list_free( &msgs->clientWillAskFor, tr_free);1892 tr_list_free( &msgs->clientAskedFor, tr_free);1893 tr_list_free( &msgs->peerAskedForFast, tr_free);1894 tr_list_free( &msgs->peerAskedFor, tr_free);1987 reqListClear( &msgs->clientWillAskFor ); 1988 reqListClear( &msgs->clientAskedFor ); 1989 reqListClear( &msgs->peerAskedForFast ); 1990 reqListClear( &msgs->peerAskedFor ); 1895 1991 tr_bitfieldFree( msgs->peerAllowedPieces ); 1896 1992 tr_bitfieldFree( msgs->clientAllowedPieces );
Note: See TracChangeset
for help on using the changeset viewer.