Changeset 7824
- Timestamp:
- Feb 4, 2009, 4:58:52 PM (12 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/peer-common.h
r7658 r7824 48 48 TR_PEER_ERROR, 49 49 TR_PEER_CANCEL, 50 TR_PEER_UPLOAD_ONLY, 51 TR_PEER_NEED_REQ 50 TR_PEER_UPLOAD_ONLY 52 51 } 53 52 PeerEventType; -
trunk/libtransmission/peer-mgr.c
r7792 r7824 1 2 1 /* 3 2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> … … 48 47 49 48 /* minimum interval for refilling peers' request lists */ 50 REFILL_PERIOD_MSEC = 333, 51 52 /* when many peers are available, keep idle ones this long */ 53 MIN_UPLOAD_IDLE_SECS = ( 30 ), 54 55 /* when few peers are available, keep idle ones this long */ 56 MAX_UPLOAD_IDLE_SECS = ( 60 * 5 ), 57 58 /* how frequently to decide which peers live and die */ 59 RECONNECT_PERIOD_MSEC = ( 2 * 1000 ), 49 REFILL_PERIOD_MSEC = 400, 60 50 61 51 /* how frequently to reallocate bandwidth */ 62 52 BANDWIDTH_PERIOD_MSEC = 500, 63 53 54 /* how frequently to decide which peers live and die */ 55 RECONNECT_PERIOD_MSEC = 500, 56 57 /* when many peers are available, keep idle ones this long */ 58 MIN_UPLOAD_IDLE_SECS = ( 30 ), 59 60 /* when few peers are available, keep idle ones this long */ 61 MAX_UPLOAD_IDLE_SECS = ( 60 * 5 ), 62 64 63 /* max # of peers to ask fer per torrent per reconnect pulse */ 65 64 MAX_RECONNECTIONS_PER_PULSE = 16, … … 75 74 MYFLAG_BANNED = 1, 76 75 76 /* use for bitwise operations w/peer_atom.myflags */ 77 77 /* unreachable for now... but not banned. 78 78 * if they try to connect to us it's okay */ … … 127 127 tr_ptrArray peers; /* tr_peer */ 128 128 tr_ptrArray webseeds; /* tr_webseed */ 129 tr_timer * reconnectTimer;130 tr_timer * rechokeTimer;131 tr_timer * refillTimer;132 129 tr_torrent * tor; 133 130 tr_peer * optimistic; /* the optimistic peer, or NULL if none */ … … 142 139 tr_ptrArray incomingHandshakes; /* tr_handshake */ 143 140 tr_timer * bandwidthTimer; 141 tr_timer * rechokeTimer; 142 tr_timer * refillTimer; 143 tr_timer * reconnectTimer; 144 144 }; 145 145 … … 380 380 381 381 memcpy( hash, t->hash, SHA_DIGEST_LENGTH ); 382 383 tr_timerFree( &t->reconnectTimer );384 tr_timerFree( &t->rechokeTimer );385 tr_timerFree( &t->refillTimer );386 382 387 383 tr_ptrArrayDestruct( &t->webseeds, (PtrArrayForeachFunc)tr_webseedFree ); … … 425 421 426 422 427 static int bandwidthPulse( void * vmgr ); 428 423 static int bandwidthPulse ( void * vmgr ); 424 static int rechokePulse ( void * vmgr ); 425 static int refillPulse ( void * vmgr ); 426 static int reconnectPulse ( void * vmgr ); 429 427 430 428 tr_peerMgr* … … 436 434 m->incomingHandshakes = TR_PTR_ARRAY_INIT; 437 435 m->bandwidthTimer = tr_timerNew( session, bandwidthPulse, m, BANDWIDTH_PERIOD_MSEC ); 436 m->rechokeTimer = tr_timerNew( session, rechokePulse, m, RECHOKE_PERIOD_MSEC ); 437 m->refillTimer = tr_timerNew( session, refillPulse, m, REFILL_PERIOD_MSEC ); 438 m->reconnectTimer = tr_timerNew( session, reconnectPulse, m, RECONNECT_PERIOD_MSEC ); 439 440 rechokePulse( m ); 441 438 442 return m; 439 443 } … … 444 448 managerLock( manager ); 445 449 450 tr_timerFree( &manager->reconnectTimer ); 451 tr_timerFree( &manager->refillTimer ); 452 tr_timerFree( &manager->rechokeTimer ); 446 453 tr_timerFree( &manager->bandwidthTimer ); 447 454 … … 728 735 } 729 736 730 static int731 refill Pulse( void * vtorrent )737 static void 738 refillTorrent( Torrent * t ) 732 739 { 733 740 tr_block_index_t block; … … 737 744 tr_webseed ** webseeds; 738 745 struct tr_blockIterator * blockIterator; 739 Torrent * t = vtorrent;740 746 tr_torrent * tor = t->tor; 741 747 742 748 if( !t->isRunning ) 743 return TRUE;749 return; 744 750 if( tr_torrentIsSeed( t->tor ) ) 745 return TRUE; 746 747 torrentLock( t ); 751 return; 752 748 753 tordbg( t, "Refilling Request Buffers..." ); 749 754 … … 817 822 tr_free( webseeds ); 818 823 tr_free( peers ); 819 820 t->refillTimer = NULL; 821 torrentUnlock( t ); 822 return FALSE; 824 } 825 826 static int 827 refillPulse( void * vmgr ) 828 { 829 tr_torrent * tor = NULL; 830 tr_peerMgr * mgr = vmgr; 831 managerLock( mgr ); 832 833 while(( tor = tr_torrentNext( mgr->session, tor ))) 834 if( tor->isRunning && !tr_torrentIsSeed( tor ) ) 835 refillTorrent( tor->torrentPeers ); 836 837 managerUnlock( mgr ); 838 return TRUE; 823 839 } 824 840 … … 867 883 tor->corruptCur += byteCount; 868 884 tor->downloadedCur -= MIN( tor->downloadedCur, byteCount ); 869 }870 871 static void872 refillSoon( Torrent * t )873 {874 if( t->refillTimer == NULL )875 t->refillTimer = tr_timerNew( t->manager->session,876 refillPulse, t,877 REFILL_PERIOD_MSEC );878 885 } 879 886 … … 943 950 a->uploadOnly = e->uploadOnly ? UPLOAD_ONLY_YES : UPLOAD_ONLY_NO; 944 951 } 945 break;946 947 case TR_PEER_NEED_REQ:948 refillSoon( t );949 952 break; 950 953 … … 1507 1510 } 1508 1511 1509 static int reconnectPulse( void * vtorrent );1510 1511 static int rechokePulse( void * vtorrent );1512 1513 1512 void 1514 1513 tr_peerMgrStartTorrent( tr_torrent * tor ) 1515 1514 { 1516 Torrent * t = tor->torrentPeers; 1517 1518 managerLock( t->manager ); 1519 1520 assert( t ); 1521 assert( ( t->isRunning != 0 ) == ( t->reconnectTimer != NULL ) ); 1522 assert( ( t->isRunning != 0 ) == ( t->rechokeTimer != NULL ) ); 1523 1524 if( !t->isRunning ) 1525 { 1526 t->isRunning = 1; 1527 1528 t->reconnectTimer = tr_timerNew( t->manager->session, 1529 reconnectPulse, t, 1530 RECONNECT_PERIOD_MSEC ); 1531 1532 t->rechokeTimer = tr_timerNew( t->manager->session, 1533 rechokePulse, t, 1534 RECHOKE_PERIOD_MSEC ); 1535 1536 reconnectPulse( t ); 1537 1538 rechokePulse( t ); 1539 1540 if( !tr_ptrArrayEmpty( &t->webseeds ) ) 1541 refillSoon( t ); 1542 } 1543 1544 managerUnlock( t->manager ); 1515 tor->torrentPeers->isRunning = TRUE; 1545 1516 } 1546 1517 … … 1550 1521 assert( torrentIsLocked( t ) ); 1551 1522 1552 t->isRunning = 0; 1553 tr_timerFree( &t->rechokeTimer ); 1554 tr_timerFree( &t->reconnectTimer ); 1523 t->isRunning = FALSE; 1555 1524 1556 1525 /* disconnect the peers. */ … … 1868 1837 1869 1838 static void 1870 rechoke ( Torrent * t )1839 rechokeTorrent( Torrent * t ) 1871 1840 { 1872 1841 int i, size, unchokedInterested; … … 1968 1937 1969 1938 static int 1970 rechokePulse( void * vtorrent ) 1971 { 1972 Torrent * t = vtorrent; 1973 1974 torrentLock( t ); 1975 rechoke( t ); 1976 torrentUnlock( t ); 1939 rechokePulse( void * vmgr ) 1940 { 1941 tr_torrent * tor = NULL; 1942 tr_peerMgr * mgr = vmgr; 1943 managerLock( mgr ); 1944 1945 while(( tor = tr_torrentNext( mgr->session, tor ))) 1946 if( tor->isRunning ) 1947 rechokeTorrent( tor->torrentPeers ); 1948 1949 managerUnlock( mgr ); 1977 1950 return TRUE; 1978 1951 } … … 2216 2189 } 2217 2190 2218 static int 2219 reconnectPulse( void * vtorrent ) 2220 { 2221 Torrent * t = vtorrent; 2191 static void 2192 reconnectTorrent( Torrent * t ) 2193 { 2222 2194 static time_t prevTime = 0; 2223 2195 static int newConnectionsThisSecond = 0; 2224 2196 time_t now; 2225 2226 torrentLock( t );2227 2197 2228 2198 now = time( NULL ); … … 2327 2297 tr_free( canClose ); 2328 2298 } 2329 2330 torrentUnlock( t ); 2299 } 2300 2301 static int 2302 reconnectPulse( void * vmgr ) 2303 { 2304 tr_torrent * tor = NULL; 2305 tr_peerMgr * mgr = vmgr; 2306 managerLock( mgr ); 2307 2308 while(( tor = tr_torrentNext( mgr->session, tor ))) 2309 if( tor->isRunning ) 2310 reconnectTorrent( tor->torrentPeers ); 2311 2312 managerUnlock( mgr ); 2331 2313 return TRUE; 2332 2314 } -
trunk/libtransmission/peer-msgs.c
r7769 r7824 421 421 422 422 static void 423 fireNeedReq( tr_peermsgs * msgs )424 {425 tr_peer_event e = blankEvent;426 e.eventType = TR_PEER_NEED_REQ;427 publish( msgs, &e );428 }429 430 static void431 423 firePeerProgress( tr_peermsgs * msgs ) 432 424 { … … 654 646 if( i != msgs->peer->clientIsInterested ) 655 647 sendInterest( msgs, i ); 656 if( i )657 fireNeedReq( msgs );658 648 } 659 649 … … 820 810 dbgmsg( msgs, "pump sent %d requests, now have %d active and %d queued", 821 811 sent, msgs->clientAskedFor.len, msgs->clientWillAskFor.len ); 822 823 if( len < max )824 fireNeedReq( msgs );825 812 } 826 813 … … 1367 1354 dbgmsg( msgs, "got Unchoke" ); 1368 1355 msgs->peer->clientIsChoked = 0; 1369 fireNeedReq( msgs );1370 1356 break; 1371 1357 … … 1393 1379 1394 1380 case BT_BITFIELD: 1395 {1396 1381 dbgmsg( msgs, "got a bitfield" ); 1397 1382 tr_peerIoReadBytes( msgs->peer->io, inbuf, msgs->peer->have->bits, msglen ); 1398 1383 updatePeerProgress( msgs ); 1399 fireNeedReq( msgs );1400 1384 break; 1401 }1402 1385 1403 1386 case BT_REQUEST: -
trunk/libtransmission/session.c
r7812 r7824 360 360 static void tr_sessionInitImpl( void * ); 361 361 362 struct init_data 363 { 364 tr_session * session; 365 const char * configDir; 366 tr_bool messageQueuingEnabled; 367 tr_benc * clientSettings; 368 }; 369 362 370 tr_session * 363 371 tr_sessionInit( const char * tag, … … 366 374 tr_benc * clientSettings ) 367 375 { 376 tr_session * session; 377 struct init_data data; 378 379 assert( tr_bencIsDict( clientSettings ) ); 380 381 /* initialize the bare skeleton of the session object */ 382 session = tr_new0( tr_session, 1 ); 383 session->bandwidth = tr_bandwidthNew( session, NULL ); 384 session->lock = tr_lockNew( ); 385 session->tag = tr_strdup( tag ); 386 session->magicNumber = SESSION_MAGIC_NUMBER; 387 388 /* start the libtransmission thread */ 389 tr_netInit( ); /* must go before tr_eventInit */ 390 tr_eventInit( session ); 391 assert( session->events != NULL ); 392 393 /* run the rest in the libtransmission thread */ 394 session->isWaiting = TRUE; 395 data.session = session; 396 data.configDir = configDir; 397 data.messageQueuingEnabled = messageQueuingEnabled; 398 data.clientSettings = clientSettings; 399 tr_runInEventThread( session, tr_sessionInitImpl, &data ); 400 while( session->isWaiting ) 401 tr_wait( 100 ); 402 403 return session; 404 } 405 406 static void 407 tr_sessionInitImpl( void * vdata ) 408 { 368 409 int64_t i; 369 410 int64_t j; … … 371 412 const char * str; 372 413 tr_benc settings; 373 tr_session * session;374 414 char * filename; 375 415 struct init_data * data = vdata; 416 tr_benc * clientSettings = data->clientSettings; 417 tr_session * session = data->session; 418 419 assert( tr_amInEventThread( session ) ); 376 420 assert( tr_bencIsDict( clientSettings ) ); 377 378 session = tr_new0( tr_session, 1 );379 session->bandwidth = tr_bandwidthNew( session, NULL );380 session->lock = tr_lockNew( );381 session->tag = tr_strdup( tag );382 session->magicNumber = SESSION_MAGIC_NUMBER;383 421 384 422 dbgmsg( "tr_sessionInit: the session's top-level bandwidth object is %p", session->bandwidth ); … … 400 438 assert( found ); 401 439 tr_setMessageLevel( i ); 402 tr_setMessageQueuing( messageQueuingEnabled );440 tr_setMessageQueuing( data->messageQueuingEnabled ); 403 441 404 442 … … 456 494 session->so_rcvbuf = 8192; 457 495 458 tr_setConfigDir( session, configDir ); 459 460 tr_netInit( ); /* must go before tr_eventInit */ 461 tr_eventInit( session ); 462 assert( session->events != NULL ); 496 tr_setConfigDir( session, data->configDir ); 497 498 tr_trackerSessionInit( session ); 463 499 464 500 session->peerMgr = tr_peerMgrNew( session ); … … 531 567 532 568 tr_bencFree( &settings ); 533 534 session->isWaiting = TRUE;535 tr_runInEventThread( session, tr_sessionInitImpl, session );536 while( session->isWaiting )537 tr_wait( 100 );538 539 return session;540 }541 static void542 tr_sessionInitImpl( void * vsession )543 {544 tr_session * session = vsession;545 569 546 570 assert( tr_isSession( session ) ); -
trunk/libtransmission/tracker.c
r7718 r7824 842 842 static int trackerPulse( void * vsession ); 843 843 844 static void 845 ensureGlobalsExist( tr_session * session ) 846 { 847 if( session->tracker == NULL ) 848 { 849 session->tracker = tr_new0( struct tr_tracker_handle, 1 ); 850 session->tracker->pulseTimer = 851 tr_timerNew( session, trackerPulse, session, 852 PULSE_INTERVAL_MSEC ); 853 dbgmsg( NULL, "creating tracker timer" ); 854 } 844 void 845 tr_trackerSessionInit( tr_session * session ) 846 { 847 assert( tr_isSession( session ) ); 848 849 session->tracker = tr_new0( struct tr_tracker_handle, 1 ); 850 session->tracker->pulseTimer = tr_timerNew( session, trackerPulse, session, PULSE_INTERVAL_MSEC ); 851 dbgmsg( NULL, "creating tracker timer" ); 855 852 } 856 853 … … 1035 1032 const tr_info * info = &torrent->info; 1036 1033 tr_tracker * t; 1037 1038 ensureGlobalsExist( torrent->session );1039 1034 1040 1035 t = tr_new0( tr_tracker, 1 ); -
trunk/libtransmission/tracker.h
r7658 r7824 31 31 32 32 void tr_trackerFree( tr_tracker * ); 33 34 /** 35 *** 36 **/ 37 38 void tr_trackerSessionInit( tr_session * ); 33 39 34 40 void tr_trackerSessionClose( tr_session * ); -
trunk/libtransmission/trevent.c
r7812 r7824 192 192 } 193 193 194 case 't': /* create timer */195 {196 tr_timer * timer;197 const size_t nwant = sizeof( timer );198 const ssize_t ngot = piperead( fd, &timer, nwant );199 if( !eh->die && ( ngot == (ssize_t)nwant ) )200 {201 dbgmsg( "adding timer in libevent thread" );202 evtimer_add( &timer->event, &timer->tv );203 }204 break;205 }206 207 194 case '\0': /* eof */ 208 195 { … … 295 282 { 296 283 assert( tr_isSession( session ) ); 297 assert( session->events );284 assert( session->events != NULL ); 298 285 299 286 return tr_amInThread( session->events->thread ); … … 342 329 343 330 tr_timer* 344 tr_timerNew( tr_session * session,345 timer_func func,346 void * user_data,347 uint64_t interval_milliseconds )331 tr_timerNew( tr_session * session, 332 timer_func func, 333 void * user_data, 334 uint64_t interval_milliseconds ) 348 335 { 349 336 tr_timer * timer; 350 337 351 assert( tr_isSession( session ) ); 352 assert( session->events != NULL ); 338 assert( tr_amInEventThread( session ) ); 353 339 354 340 timer = tr_new0( tr_timer, 1 ); 355 tr_timevalMsec( interval_milliseconds, &timer->tv );356 341 timer->func = func; 357 342 timer->user_data = user_data; 358 343 timer->eh = session->events; 344 345 tr_timevalMsec( interval_milliseconds, &timer->tv ); 359 346 evtimer_set( &timer->event, timerCallback, timer ); 360 361 if( tr_amInThread( session->events->thread ) ) 362 { 363 evtimer_add( &timer->event, &timer->tv ); 364 } 365 else 366 { 367 const char ch = 't'; 368 int fd = session->events->fds[1]; 369 tr_lock * lock = session->events->lock; 370 371 tr_lockLock( lock ); 372 pipewrite( fd, &ch, 1 ); 373 pipewrite( fd, &timer, sizeof( timer ) ); 374 tr_lockUnlock( lock ); 375 } 347 evtimer_add( &timer->event, &timer->tv ); 376 348 377 349 return timer; -
trunk/libtransmission/webseed.c
r7658 r7824 60 60 if( w->callback ) 61 61 w->callback( NULL, e, w->callback_userdata ); 62 }63 64 static void65 fireNeedReq( tr_webseed * w )66 {67 tr_peer_event e = blankEvent;68 e.eventType = TR_PEER_NEED_REQ;69 publish( w, &e );70 62 } 71 63 … … 181 173 if( w->dead ) 182 174 tr_webseedFree( w ); 183 else {175 else 184 176 fireClientGotBlock( w, w->pieceIndex, w->pieceOffset, w->byteCount ); 185 fireNeedReq( w );186 }187 177 } 188 178 }
Note: See TracChangeset
for help on using the changeset viewer.