Changeset 12184
- Timestamp:
- Mar 17, 2011, 6:51:31 PM (10 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/announcer-common.h
r12152 r12184 239 239 void * user_data ); 240 240 241 void tr_tracker_udp_ upkeep( tr_session * session );241 void tr_tracker_udp_start_shutdown( tr_session * session ); 242 242 243 243 #endif /* _TR_ANNOUNCER_COMMON_H_ */ -
trunk/libtransmission/announcer-udp.c
r12180 r12184 20 20 21 21 #include "transmission.h" 22 #include "announcer.h" 22 23 #include "announcer-common.h" 23 24 #include "crypto.h" … … 436 437 tau_transaction_t connection_transaction_id; 437 438 439 time_t close_at; 440 438 441 tr_ptrArray announces; 439 442 tr_ptrArray scrapes; … … 442 445 static void tau_tracker_upkeep( struct tau_tracker * ); 443 446 444 #if 0445 447 static void 446 448 tau_tracker_free( struct tau_tracker * t ) … … 454 456 tr_free( t ); 455 457 } 456 #endif457 458 458 459 static void … … 524 525 } 525 526 527 static tr_bool 528 tau_tracker_is_empty( const struct tau_tracker * tracker ) 529 { 530 return tr_ptrArrayEmpty( &tracker->announces ) 531 && tr_ptrArrayEmpty( &tracker->scrapes ); 532 } 533 526 534 static void 527 535 tau_tracker_upkeep( struct tau_tracker * tracker ) … … 541 549 542 550 /* are there any requests pending? */ 543 if( tr_ptrArrayEmpty( &tracker->announces ) && 544 tr_ptrArrayEmpty( &tracker->scrapes ) ) 551 if( tau_tracker_is_empty( tracker ) ) 545 552 return; 546 553 … … 584 591 for( i=0, n=tr_ptrArraySize(reqs); i<n; ++i ) 585 592 { 593 tr_bool remove_request = FALSE; 586 594 struct tau_announce_request * req = tr_ptrArrayNth( reqs, i ); 587 595 if( is_connected && !req->sent_at ) { … … 589 597 req->sent_at = now; 590 598 tau_tracker_send_request( tracker, req->payload, req->payload_len ); 599 remove_request = req->callback == NULL; 591 600 } 592 601 else if( req->created_at + TAU_REQUEST_TTL < now ) { 593 602 tau_announce_request_fail( tracker->session, req, FALSE, TRUE, NULL ); 603 remove_request = TRUE; 604 } 605 if( tracker->close_at && ( tracker->close_at <= time(NULL) ) ) 606 remove_request = TRUE; 607 if( remove_request ) { 594 608 tau_announce_request_free( req ); 595 609 tr_ptrArrayRemove( reqs, i ); … … 603 617 for( i=0, n=tr_ptrArraySize(reqs); i<n; ++i ) 604 618 { 619 tr_bool remove_request = FALSE; 605 620 struct tau_scrape_request * req = tr_ptrArrayNth( reqs, i ); 606 621 if( is_connected && !req->sent_at ) { … … 608 623 req->sent_at = now; 609 624 tau_tracker_send_request( tracker, req->payload, req->payload_len ); 625 remove_request = req->callback == NULL; 610 626 } 611 627 else if( req->created_at + TAU_REQUEST_TTL < now ) { 612 628 tau_scrape_request_fail( tracker->session, req, FALSE, TRUE, NULL ); 629 remove_request = TRUE; 630 } 631 if( tracker->close_at && ( tracker->close_at <= time(NULL) ) ) 632 remove_request = TRUE; 633 if( remove_request ) { 613 634 tau_scrape_request_free( req ); 614 635 tr_ptrArrayRemove( reqs, i ); … … 740 761 tr_ptrArrayForeach( &tau->trackers, 741 762 (PtrArrayForeachFunc)tau_tracker_upkeep ); 763 } 764 765 tr_bool 766 tr_tracker_udp_is_empty( const tr_session * session ) 767 { 768 int i; 769 int n; 770 struct tr_announcer_udp * tau = session->announcer_udp; 771 772 if( tau != NULL ) 773 for( i=0, n=tr_ptrArraySize(&tau->trackers); i<n; ++i ) 774 if( !tau_tracker_is_empty( tr_ptrArrayNth( &tau->trackers, i ) ) ) 775 return FALSE; 776 777 return TRUE; 778 } 779 780 /* drop dead now. */ 781 void 782 tr_tracker_udp_close( tr_session * session ) 783 { 784 struct tr_announcer_udp * tau = session->announcer_udp; 785 786 if( tau != NULL ) 787 { 788 session->announcer_udp = NULL; 789 tr_ptrArrayDestruct( &tau->trackers, (PtrArrayForeachFunc)tau_tracker_free ); 790 tr_free( tau ); 791 } 792 793 } 794 795 /* start shutting down. 796 This doesn't destroy everything if there are requests, 797 but sets a deadline on how much longer to wait for the remaining ones */ 798 void 799 tr_tracker_udp_start_shutdown( tr_session * session ) 800 { 801 const time_t now = time( NULL ); 802 struct tr_announcer_udp * tau = session->announcer_udp; 803 804 if( tau != NULL ) 805 { 806 int i, n; 807 for( i=0, n=tr_ptrArraySize(&tau->trackers); i<n; ++i ) 808 { 809 struct tau_tracker * tracker = tr_ptrArrayNth( &tau->trackers, i ); 810 tracker->close_at = now + 3; 811 tau_tracker_upkeep( tracker ); 812 } 813 } 742 814 } 743 815 -
trunk/libtransmission/announcer.c
r12182 r12184 125 125 int slotsAvailable; 126 126 int key; 127 time_t lpdUpkeepAt;128 127 time_t tauUpkeepAt; 129 128 } … … 134 133 { 135 134 return announcer->slotsAvailable < 1; 136 }137 138 static inline time_t139 jitterize( const int val )140 {141 const double jitter = 0.1;142 assert( val > 0 );143 return val + tr_cryptoWeakRandInt((int)(1 + val * jitter));144 135 } 145 136 … … 159 150 a->session = session; 160 151 a->slotsAvailable = MAX_CONCURRENT_TASKS; 161 a->lpdUpkeepAt = tr_time() + jitterize(5);162 152 a->upkeepTimer = evtimer_new( session->event_base, onUpkeepTimer, a ); 163 153 tr_timerAdd( a->upkeepTimer, UPKEEP_INTERVAL_SECS, 0 ); … … 174 164 175 165 flushCloseMessages( announcer ); 166 167 tr_tracker_udp_start_shutdown( session ); 176 168 177 169 event_free( announcer->upkeepTimer ); … … 1492 1484 onUpkeepTimer( int foo UNUSED, short bar UNUSED, void * vannouncer ) 1493 1485 { 1486 tr_announcer * announcer = vannouncer; 1487 tr_session * session = announcer->session; 1488 const tr_bool is_closing = session->isClosed; 1494 1489 const time_t now = tr_time( ); 1495 tr_announcer * announcer = vannouncer; 1496 tr_sessionLock( announcer->session );1490 1491 tr_sessionLock( session ); 1497 1492 1498 1493 /* maybe send out some "stopped" messages for closed torrents */ … … 1500 1495 1501 1496 /* maybe send out some announcements to trackers */ 1502 announceMore( announcer ); 1497 if( !is_closing ) 1498 announceMore( announcer ); 1503 1499 1504 1500 /* TAU upkeep */ 1505 1501 if( announcer->tauUpkeepAt <= now ) { 1506 1502 announcer->tauUpkeepAt = now + TAU_UPKEEP_INTERVAL_SECS; 1507 tr_tracker_udp_upkeep( announcer->session );1503 tr_tracker_udp_upkeep( session ); 1508 1504 } 1509 1505 … … 1511 1507 tr_timerAdd( announcer->upkeepTimer, UPKEEP_INTERVAL_SECS, 0 ); 1512 1508 1513 tr_sessionUnlock( announcer->session );1509 tr_sessionUnlock( session ); 1514 1510 } 1515 1511 -
trunk/libtransmission/announcer.h
r11844 r12184 105 105 int trackerCount ); 106 106 107 /*** 108 **** 109 ***/ 110 111 void tr_tracker_udp_upkeep( tr_session * session ); 112 113 void tr_tracker_udp_close( tr_session * session ); 114 115 tr_bool tr_tracker_udp_is_empty( const tr_session * session ); 116 117 107 118 108 119 #endif /* _TR_ANNOUNCER_H_ */ -
trunk/libtransmission/session.c
r12183 r12184 22 22 #include <dirent.h> /* opendir */ 23 23 24 #include <event2/dns.h> /* evdns_base_free() */ 24 25 #include <event2/event.h> 25 26 … … 1734 1735 1735 1736 tr_utpClose( session ); 1736 tr_ udpUninit( session );1737 tr_dhtUninit( session ); 1737 1738 1738 1739 event_free( session->saveTimer ); … … 1759 1760 tr_free( torrents ); 1760 1761 1762 /* Close the announcer *after* closing the torrents 1763 so that all the &event=stopped messages will be 1764 queued to be sent by tr_announcerClose() */ 1765 tr_announcerClose( session ); 1766 1767 /* and this goes *after* announcer close so that 1768 it won't be idle until the announce events are sent... */ 1769 tr_webClose( session, TR_WEB_CLOSE_WHEN_IDLE ); 1770 1761 1771 tr_cacheFree( session->cache ); 1762 1772 session->cache = NULL; 1763 tr_announcerClose( session ); 1773 1774 /* gotta keep udp running long enough to send out all 1775 the &event=stopped UDP tracker messages */ 1776 while( !tr_tracker_udp_is_empty( session ) ) { 1777 tr_tracker_udp_upkeep( session ); 1778 tr_wait_msec( 100 ); 1779 } 1780 1781 /* we had to wait until UDP trackers were closed before closing these: */ 1782 evdns_base_free( session->evdns_base, 0 ); 1783 session->evdns_base = NULL; 1784 tr_tracker_udp_close( session ); 1785 tr_udpUninit( session ); 1786 1764 1787 tr_statsClose( session ); 1765 1788 tr_peerMgrFree( session->peerMgr ); 1766 tr_webClose( session, TR_WEB_CLOSE_WHEN_IDLE );1767 1789 1768 1790 closeBlocklists( session ); … … 1802 1824 * for a bit while they tell the router & tracker 1803 1825 * that we're closing now */ 1804 while( ( session->shared || session->web || session->announcer )1826 while( ( session->shared || session->web || session->announcer || session->announcer_udp ) 1805 1827 && !deadlineReached( deadline ) ) 1806 1828 { -
trunk/libtransmission/tr-udp.c
r12177 r12184 290 290 tr_udpUninit(tr_session *ss) 291 291 { 292 tr_dhtUninit(ss);293 294 292 if(ss->udp_socket >= 0) { 295 293 tr_netCloseSocket( ss->udp_socket ); -
trunk/libtransmission/tr-utp.c
r12096 r12184 170 170 tr_session *ss) 171 171 { 172 if( utp_timer == NULL)172 if( !ss->isClosed && !utp_timer ) 173 173 { 174 174 utp_timer = evtimer_new( ss->event_base, timer_callback, ss ); -
trunk/libtransmission/trevent.c
r12141 r12184 225 225 { 226 226 struct event_base * base; 227 struct evdns_base * evdns_base;228 227 tr_event_handle * eh = veh; 229 228 … … 235 234 /* create the libevent bases */ 236 235 base = event_base_new( ); 237 evdns_base = evdns_base_new( base, TRUE );238 236 239 237 /* set the struct's fields */ 240 238 eh->base = base; 241 239 eh->session->event_base = base; 242 eh->session->evdns_base = evdns_base ;240 eh->session->evdns_base = evdns_base_new( base, TRUE ); 243 241 eh->session->events = eh; 244 242 … … 254 252 /* shut down the thread */ 255 253 tr_lockFree( eh->lock ); 256 evdns_base_free( evdns_base, FALSE );257 254 event_base_free( base ); 258 255 eh->session->events = NULL; -
trunk/libtransmission/web.c
r12177 r12184 331 331 if( web->close_mode == TR_WEB_CLOSE_NOW ) 332 332 break; 333 if( ( web->close_mode == TR_WEB_CLOSE_WHEN_IDLE ) && !taskCount)333 if( ( web->close_mode == TR_WEB_CLOSE_WHEN_IDLE ) && ( web->tasks == NULL ) ) 334 334 break; 335 335 … … 350 350 if( msec < 0 ) 351 351 msec = THREADFUNC_MAX_SLEEP_MSEC; 352 if( session->isClosed ) 353 msec = 100; /* on shutdown, call perform() more frequently */ 352 354 if( msec > 0 ) 353 355 { … … 369 371 t.tv_sec = usec / 1000000; 370 372 t.tv_usec = usec % 1000000; 371 372 373 tr_select( max_fd+1, &r_fd_set, &w_fd_set, &c_fd_set, &t ); 373 374 } … … 400 401 } 401 402 } 403 404 #if 0 405 { 406 tr_list * l; 407 for( l=web->tasks; l!=NULL; l=l->next ) 408 fprintf( stderr, "still pending: %s\n", ((struct tr_web_task*)l->data)->url ); 409 } 410 fprintf( stderr, "loop is ending... web is closing\n" ); 411 #endif 402 412 } 403 413
Note: See TracChangeset
for help on using the changeset viewer.