Changeset 10150
- Timestamp:
- Feb 10, 2010, 2:59:15 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/announcer.c
r10149 r10150 352 352 uint64_t byteCounts[3]; 353 353 354 tr_ptrArray announceEvents; /* const char* */ 355 354 356 tr_ptrArray trackers; /* tr_tracker_item */ 355 357 tr_tracker_item * currentTracker; … … 369 371 370 372 time_t announceAt; 371 const char * announceEvent;373 //const char * announceEvent; 372 374 373 375 /* unique lookup key */ … … 399 401 t = tr_new0( tr_tier, 1 ); 400 402 t->key = nextKey++; 403 t->announceEvents = TR_PTR_ARRAY_INIT; 401 404 t->trackers = TR_PTR_ARRAY_INIT; 402 405 t->currentTracker = NULL; … … 416 419 tr_tier * tier = vtier; 417 420 tr_ptrArrayDestruct( &tier->trackers, trackerFree ); 421 tr_ptrArrayDestruct( &tier->announceEvents, NULL ); 418 422 tr_free( tier ); 419 423 } … … 862 866 863 867 static void 864 tierClearNextAnnounce( tr_tier * tier ) 865 { 866 tier->announceAt = 0; 867 tier->announceEvent = NULL; 868 dbgmsg( tier, "cleared out announceEvent -- no announces pending." ); 869 } 870 871 static void 872 tierSetNextAnnounce( tr_tier * tier, const char * announceEvent, time_t announceAt ) 868 tierAddAnnounce( tr_tier * tier, const char * announceEvent, time_t announceAt ) 873 869 { 874 870 assert( tier != NULL ); 875 assert( announceEvent != NULL ); 876 877 if( !strcmp( announceEvent, "manual" ) && !tierCanManualAnnounce( tier ) ) 878 return; 879 871 assert( event != NULL ); 872 873 tr_ptrArrayAppend( &tier->announceEvents, (void*)announceEvent ); 880 874 tier->announceAt = announceAt; 881 tier->announceEvent = announceEvent; 882 dbgmsg( tier, " next announce event is \"%s\"in %d seconds\n", announceEvent, (int)difftime(announceAt,time(NULL)) );883 } 884 885 static void 886 torrent SetNextAnnounce( tr_torrent * tor, const char * announceEvent, time_t announceAt )875 876 dbgmsg( tier, "appended event \"%s\"; announcing in %d seconds\n", announceEvent, (int)difftime(announceAt,time(NULL)) ); 877 } 878 879 static void 880 torrentAddAnnounce( tr_torrent * tor, const char * announceEvent, time_t announceAt ) 887 881 { 888 882 int i; … … 895 889 n = tr_ptrArraySize( &tiers->tiers ); 896 890 for( i=0; i<n; ++i ) 897 tierSetNextAnnounce( tr_ptrArrayNth( &tiers->tiers, i ), announceEvent, announceAt ); 898 } 899 891 tierAddAnnounce( tr_ptrArrayNth( &tiers->tiers, i ), announceEvent, announceAt ); 892 } 893 894 void 895 tr_announcerTorrentStarted( tr_torrent * tor ) 896 { 897 torrentAddAnnounce( tor, "started", tr_time( ) ); 898 } 900 899 void 901 900 tr_announcerManualAnnounce( tr_torrent * tor ) 902 901 { 903 torrentSetNextAnnounce( tor, "manual", tr_time( ) ); 904 } 905 void 906 tr_announcerTorrentStarted( tr_torrent * tor ) 907 { 908 torrentSetNextAnnounce( tor, "started", tr_time( ) ); 902 torrentAddAnnounce( tor, "", tr_time( ) ); 909 903 } 910 904 void 911 905 tr_announcerTorrentStopped( tr_torrent * tor ) 912 906 { 913 torrent SetNextAnnounce( tor, "stopped", tr_time( ) );907 torrentAddAnnounce( tor, "stopped", tr_time( ) ); 914 908 } 915 909 void 916 910 tr_announcerTorrentCompleted( tr_torrent * tor ) 917 911 { 918 torrent SetNextAnnounce( tor, "completed", tr_time( ) );912 torrentAddAnnounce( tor, "completed", tr_time( ) ); 919 913 } 920 914 void … … 1257 1251 tr_bool success = FALSE; 1258 1252 const time_t now = time ( NULL ); 1259 const tr_bool isStopped = !strcmp( data->event, "stopped" ); 1253 const char * announceEvent = data->event; 1254 const tr_bool isStopped = !strcmp( announceEvent, "stopped" ); 1260 1255 1261 1256 if( announcer && tier ) … … 1325 1320 dbgmsg( tier, "No response from tracker... retrying in %d seconds.", interval ); 1326 1321 tier->manualAnnounceAllowedAt = ~(time_t)0; 1327 tier SetNextAnnounce( tier, tier->announceEvent, now + interval );1322 tierAddAnnounce( tier, announceEvent, now + interval ); 1328 1323 } 1329 1324 else if( 200 <= responseCode && responseCode <= 299 ) … … 1341 1336 tier->manualAnnounceAllowedAt = now + tier->announceMinIntervalSec; 1342 1337 1343 if( strcmp( tier->announceEvent, "stopped" ) == 0 ) 1344 tierClearNextAnnounce( tier ); 1345 else 1346 tierSetNextAnnounce( tier, "", now + interval ); 1338 /* if we're running and the queue is empty, add the next update */ 1339 if( !isStopped && !tr_ptrArraySize( &tier->announceEvents ) ) 1340 { 1341 tierAddAnnounce( tier, "", now + interval ); 1342 } 1347 1343 } 1348 1344 else if( 300 <= responseCode && responseCode <= 399 ) … … 1351 1347 const int interval = 5; 1352 1348 dbgmsg( tier, "got a redirect. retrying in %d seconds", interval ); 1353 tier SetNextAnnounce( tier, tier->announceEvent, now + interval );1349 tierAddAnnounce( tier, announceEvent, now + interval ); 1354 1350 tier->manualAnnounceAllowedAt = now + tier->announceMinIntervalSec; 1355 1351 } … … 1362 1358 publishErrorMessageAndStop( tier, _( "Tracker returned a 4xx message" ) ); 1363 1359 tier->manualAnnounceAllowedAt = ~(time_t)0; 1364 tierClearNextAnnounce( tier );1365 1360 } 1366 1361 else if( 500 <= responseCode && responseCode <= 599 ) … … 1372 1367 const int interval = getRetryInterval( tier->currentTracker->host ); 1373 1368 tier->manualAnnounceAllowedAt = ~(time_t)0; 1374 tier SetNextAnnounce( tier, tier->announceEvent, now + interval );1369 tierAddAnnounce( tier, announceEvent, now + interval ); 1375 1370 } 1376 1371 else … … 1380 1375 dbgmsg( tier, "Invalid response from tracker... retrying in two minutes." ); 1381 1376 tier->manualAnnounceAllowedAt = ~(time_t)0; 1382 tier SetNextAnnounce( tier, tier->announceEvent, now + interval );1377 tierAddAnnounce( tier, announceEvent, now + interval ); 1383 1378 } 1384 1379 … … 1393 1388 tier->currentTracker->host->lastSuccessfulRequest = now; 1394 1389 } 1395 1396 if( !success )1390 else if( responseCode != HTTP_OK ) 1391 { 1397 1392 tierIncrementTracker( tier ); 1393 1394 tr_ptrArrayInsert( &tier->announceEvents, (void*)announceEvent, 0 ); 1395 } 1398 1396 } 1399 1397 … … 1406 1404 } 1407 1405 1408 static const char * 1409 getAnnounceEvent( const tr_tier * tier ) 1410 { 1411 const char * event; 1406 static const char* 1407 getNextAnnounceEvent( tr_tier * tier ) 1408 { 1409 int i, n; 1410 int pos = -1; 1411 tr_ptrArray tmp; 1412 char ** events; 1413 const char * str = NULL; 1412 1414 1413 1415 assert( tier != NULL ); … … 1415 1417 assert( tr_isTorrent( tier->tor ) ); 1416 1418 1417 /* BEP 21: "In order to tell the tracker that a peer is a partial seed, 1418 * it MUST send an event=paused parameter in every announce while 1419 * it is a partial seed." */ 1419 /* rule #1: if there's a "stopped" in the queue, ignore everything before it */ 1420 events = (char**) tr_ptrArrayPeek( &tier->announceEvents, &n ); 1421 for( i=0; pos<0 && i<n; ++i ) 1422 if( !strcmp( events[i], "stopped" ) ) 1423 pos = i; 1424 1425 fprintf( stderr, "in the queue: " ); 1426 for( i=0; i<n; ++i ) fprintf( stderr, "(%d)%s, ", i, events[i] ); 1427 fprintf( stderr, "\n" ); 1428 1429 /* rule #2: if the next two events are the same, ignore the first one */ 1430 for( i=0; pos<0 && i<=n-2; ++i ) 1431 if( strcmp( events[i], events[i+1] ) ) 1432 pos = i; 1433 1434 /* otherwise use the next announce event in line */ 1435 if( ( pos < 0 ) && ( n > 0 ) ) 1436 pos = 0; 1437 1438 /* rule #3: BEP 21: "In order to tell the tracker that a peer is a 1439 * partial seed, it MUST send an event=paused parameter in every 1440 * announce while it is a partial seed." */ 1441 str = pos>=0 ? events[pos] : NULL; 1420 1442 if( tr_cpGetStatus( &tier->tor->completion ) == TR_PARTIAL_SEED ) 1421 if( strcmp( tier->announceEvent, "stopped" ) ) 1422 return "paused"; 1423 1424 event = tier->announceEvent; 1425 1426 if( !strcmp( event, "manual" ) ) 1427 return "started"; 1428 1429 return event; 1443 if( !str || !strcmp( str, "stopped" ) ) 1444 str = "paused"; 1445 1446 /* announceEvents array upkeep */ 1447 fprintf( stderr, "what's left in the queue: " ); 1448 tmp = TR_PTR_ARRAY_INIT; 1449 for( i=pos+1; i<n; ++i ) { 1450 fprintf( stderr, "(%d)%s, ", i, events[i] ); 1451 tr_ptrArrayAppend( &tmp, events[i] ); 1452 } 1453 tr_ptrArrayDestruct( &tier->announceEvents, NULL ); 1454 tier->announceEvents = tmp; 1455 fprintf( stderr, "\n" ); 1456 1457 fprintf( stderr, "returning [%s] (pos %d)\n", (str?str:"(null)"), pos ); 1458 1459 return str; 1430 1460 } 1431 1461 … … 1433 1463 tierAnnounce( tr_announcer * announcer, tr_tier * tier ) 1434 1464 { 1435 char * url; 1436 struct announce_data * data; 1437 const tr_torrent * tor = tier->tor; 1438 const time_t now = tr_time( ); 1465 const char * announceEvent = getNextAnnounceEvent( tier ); 1439 1466 1440 1467 assert( !tier->isAnnouncing ); 1441 1468 1442 data = tr_new0( struct announce_data, 1 ); 1443 data->torrentId = tr_torrentId( tor ); 1444 data->tierId = tier->key; 1445 data->isRunningOnSuccess = tor->isRunning; 1446 data->timeSent = now; 1447 data->event = getAnnounceEvent( tier ); 1448 url = createAnnounceURL( announcer, tor, tier, data->event ); 1449 1450 tier->isAnnouncing = TRUE; 1451 tier->lastAnnounceStartTime = now; 1452 --announcer->slotsAvailable; 1453 tr_webRun( announcer->session, url, NULL, onAnnounceDone, data ); 1454 1455 tr_free( url ); 1469 if( announceEvent != NULL ) 1470 { 1471 char * url; 1472 struct announce_data * data; 1473 const tr_torrent * tor = tier->tor; 1474 const time_t now = tr_time( ); 1475 1476 data = tr_new0( struct announce_data, 1 ); 1477 data->torrentId = tr_torrentId( tor ); 1478 data->tierId = tier->key; 1479 data->isRunningOnSuccess = tor->isRunning; 1480 data->timeSent = now; 1481 data->event = announceEvent; 1482 url = createAnnounceURL( announcer, tor, tier, data->event ); 1483 1484 tier->isAnnouncing = TRUE; 1485 tier->lastAnnounceStartTime = now; 1486 --announcer->slotsAvailable; 1487 tr_webRun( announcer->session, url, NULL, onAnnounceDone, data ); 1488 1489 tr_free( url ); 1490 } 1456 1491 } 1457 1492 … … 1651 1686 return !tier->isAnnouncing 1652 1687 && !tier->isScraping 1653 && ( tier->announce Event != NULL)1654 && ( t ier->announceAt <= now);1688 && ( tier->announceAt <= now ) 1689 && ( tr_ptrArraySize( &tier->announceEvents ) != 0 ); 1655 1690 } 1656 1691
Note: See TracChangeset
for help on using the changeset viewer.