Changeset 2462
- Timestamp:
- Jul 23, 2007, 3:00:20 AM (15 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/fastresume.c
r2443 r2462 147 147 } 148 148 149 void fastResumeSave( const tr_torrent_t * tor ) 149 void 150 tr_fastResumeSave( const tr_torrent_t * tor ) 150 151 { 151 152 char path[MAX_PATH_LENGTH]; … … 391 392 bitfield.bits = walk; 392 393 tr_cpBlockBitfieldSet( tor->completion, &bitfield ); 394 /* FIXME: remove the "unchecked pieces" */ 393 395 } 394 396 … … 397 399 } 398 400 399 static int401 static uint64_t 400 402 fastResumeLoadOld( tr_torrent_t * tor, 401 403 tr_bitfield_t * uncheckedPieces, 402 404 FILE * file ) 403 405 { 406 uint64_t ret = 0; 407 404 408 /* Check the size */ 405 409 const int size = 4 + FR_PROGRESS_LEN( tor ); … … 423 427 fclose( file ); 424 428 429 ret |= TR_FR_PROGRESS; 425 430 tr_inf( "Fast resuming successful (version 0)" ); 426 427 return 0;428 } 429 430 int431 fastResumeLoad ( tr_torrent_t * tor,432 tr_bitfield_t * uncheckedPieces )431 432 return ret; 433 } 434 435 static uint64_t 436 fastResumeLoadImpl ( tr_torrent_t * tor, 437 tr_bitfield_t * uncheckedPieces ) 433 438 { 434 439 char path[MAX_PATH_LENGTH]; … … 437 442 uint8_t id; 438 443 uint32_t len; 439 int ret;444 uint64_t ret = 0; 440 445 441 446 assert( tor != NULL ); … … 445 450 fastResumeFileName( path, sizeof path, tor, 1 ); 446 451 file = fopen( path, "r" ); 447 if( NULL ==file )452 if( !file ) 448 453 { 449 454 if( ENOENT == errno ) … … 451 456 fastResumeFileName( path, sizeof path, tor, 0 ); 452 457 file = fopen( path, "r" ); 453 if( NULL !=file )458 if( !file ) 454 459 { 455 goto good; 460 fastResumeFileName( path, sizeof path, tor, 1 ); 461 tr_inf( "Couldn't open '%s' for reading", path ); 462 return ret; 456 463 } 457 fastResumeFileName( path, sizeof path, tor, 1 );458 464 } 459 tr_inf( "Could not open '%s' for reading", path ); 460 return 1; 461 } 462 good: 465 } 466 463 467 tr_dbg( "Resume file '%s' loaded", path ); 464 468 … … 473 477 tr_inf( "Resume file has version %d, not supported", version ); 474 478 fclose( file ); 475 return 1; 476 } 477 478 ret = 1; 479 return ret; 480 } 481 479 482 /* read each block of data */ 480 483 while( 1 == fread( &id, 1, 1, file ) && 1 == fread( &len, 4, 1, file ) ) … … 486 489 if( (uint32_t)FR_PROGRESS_LEN( tor ) == len ) 487 490 { 488 ret = fastResumeLoadProgress( tor, uncheckedPieces, file );489 490 if( r et && ( feof(file) || ferror(file) ) )491 const int rret = fastResumeLoadProgress( tor, uncheckedPieces, file ); 492 493 if( rret && ( feof(file) || ferror(file) ) ) 491 494 { 492 495 fclose( file ); 493 return 1;496 return ret; 494 497 } 495 498 499 ret |= TR_FR_PROGRESS; 496 500 continue; 497 501 } … … 503 507 if( len == (uint32_t)(2 * tor->info.fileCount) ) 504 508 { 505 ret = loadPriorities( tor, file );506 507 if( r et && ( feof(file) || ferror(file) ) )509 const int rret = loadPriorities( tor, file ); 510 511 if( rret && ( feof(file) || ferror(file) ) ) 508 512 { 509 513 fclose( file ); 510 return 1;514 return ret; 511 515 } 512 516 517 ret |= TR_FR_PRIORITY; 513 518 continue; 514 519 } … … 519 524 if( len == FR_SPEED_LEN ) 520 525 { 521 ret = loadSpeeds( tor, file );522 523 if( r et && ( feof(file) || ferror(file) ) )526 const int rret = loadSpeeds( tor, file ); 527 528 if( rret && ( feof(file) || ferror(file) ) ) 524 529 { 525 530 fclose( file ); 526 return 1;531 return ret; 527 532 } 528 533 534 ret |= TR_FR_SPEEDLIMIT; 529 535 continue; 530 536 } … … 538 544 { 539 545 fclose( file ); 540 return 1;546 return ret; 541 547 } 542 548 tor->downloadedCur = 0; 549 ret |= TR_FR_DOWNLOADED; 543 550 continue; 544 551 } … … 552 559 { 553 560 fclose( file ); 554 return 1;561 return ret; 555 562 } 563 tor->uploadedCur = 0; 564 ret |= TR_FR_UPLOADED; 556 565 continue; 557 566 } … … 567 576 free( buf ); 568 577 fclose( file ); 569 return 1;578 return ret; 570 579 } 571 580 used = tr_torrentAddCompact( tor, TR_PEER_FROM_CACHE, … … 574 583 len / 6, used ); 575 584 free( buf ); 585 ret |= TR_FR_PEERS; 576 586 } 577 587 continue; … … 587 597 588 598 fclose( file ); 589 590 if( !ret )591 {592 tr_inf( "Fast resuming successful" );593 }594 595 599 return ret; 596 600 } 601 602 uint64_t 603 tr_fastResumeLoad( tr_torrent_t * tor, 604 tr_bitfield_t * uncheckedPieces ) 605 { 606 const uint64_t ret = fastResumeLoadImpl( tor, uncheckedPieces ); 607 608 if( ! ( ret & TR_FR_PROGRESS ) ) 609 tr_bitfieldAddRange( uncheckedPieces, 0, tor->info.pieceCount ); 610 611 return ret; 612 } -
trunk/libtransmission/fastresume.h
r2315 r2462 26 26 #define TR_FAST_RESUME_H 27 27 28 void fastResumeSave( const tr_torrent_t * tor );28 void tr_fastResumeSave( const tr_torrent_t * tor ); 29 29 30 int fastResumeLoad( tr_torrent_t * tor, 31 tr_bitfield_t * uncheckedPieces ); 30 enum 31 { 32 TR_FR_DOWNLOADED = (1<<0), 33 TR_FR_UPLOADED = (1<<1), 34 TR_FR_PEERS = (1<<2), 35 TR_FR_PROGRESS = (1<<3), 36 TR_FR_PRIORITY = (1<<4), 37 TR_FR_SPEEDLIMIT = (1<<5) 38 }; 39 40 /** 41 * Returns a bitwise-or'ed set of the data loaded from fastresume 42 */ 43 uint64_t tr_fastResumeLoad( tr_torrent_t * tor, 44 tr_bitfield_t * uncheckedPieces ); 32 45 33 46 #endif -
trunk/libtransmission/inout.c
r2348 r2462 13 13 #include <unistd.h> 14 14 #include "transmission.h" 15 #include "fastresume.h"16 15 #include "fdlimit.h" 17 16 … … 212 211 } 213 212 214 int 215 tr_ioCheckFiles( tr_torrent_t * tor, int mode ) 216 { 217 int i; 218 tr_bitfield_t * uncheckedPieces = tr_bitfieldNew( tor->info.pieceCount ); 219 220 tr_cpReset( tor->completion ); 221 222 tr_bitfieldClear( uncheckedPieces ); 223 224 if( (mode==TR_RECHECK_FORCE) || fastResumeLoad( tor, uncheckedPieces ) ) 225 tr_bitfieldAddRange( uncheckedPieces, 0, tor->info.pieceCount ); 226 227 if( tr_bitfieldIsEmpty( uncheckedPieces ) ) { 228 tr_bitfieldFree( uncheckedPieces ); 229 return TR_OK; 230 } 231 232 if( mode == TR_RECHECK_FAST ) { 233 tr_bitfieldFree( uncheckedPieces ); 234 return TR_ERROR_IO_OTHER; 235 } 236 237 tr_inf( "Verifying some pieces of \"%s\"", tor->info.name ); 238 239 for( i=0; i<tor->info.pieceCount; ++i ) 240 { 241 if( !tr_bitfieldHas( uncheckedPieces, i ) ) 242 continue; 243 244 tr_dbg ( "Checking piece %d because it's not in fast-resume", i ); 245 246 tr_torrentSetHasPiece( tor, i, !checkPiece( tor, i ) ); 247 248 tr_bitfieldRem( uncheckedPieces, i ); 249 } 250 251 fastResumeSave( tor ); 252 tr_bitfieldFree( uncheckedPieces ); 253 return TR_OK; 213 void 214 tr_ioCheckFiles( tr_torrent_t * tor ) 215 { 216 if( tor->uncheckedPieces != NULL ) 217 { 218 int i; 219 tr_bitfield_t * p = tor->uncheckedPieces; 220 tor->uncheckedPieces = NULL; 221 222 tr_inf( "Verifying some pieces of \"%s\"", tor->info.name ); 223 224 for( i=0; i<tor->info.pieceCount; ++i ) 225 { 226 if( !tr_bitfieldHas( p, i ) ) 227 continue; 228 229 tr_torrentSetHasPiece( tor, i, !checkPiece( tor, i ) ); 230 } 231 232 tr_bitfieldFree( p ); 233 tor->fastResumeDirty = TRUE; 234 } 254 235 } 255 236 … … 259 240 260 241 tr_io_t* 261 tr_io InitFast( tr_torrent_t * tor )242 tr_ioNew ( tr_torrent_t * tor ) 262 243 { 263 244 tr_io_t * io = tr_calloc( 1, sizeof( tr_io_t ) ); 264 245 io->tor = tor; 265 266 if( tr_ioCheckFiles( tor, TR_RECHECK_FAST ) )267 {268 tr_free( io );269 io = NULL;270 }271 272 246 return io; 273 247 } … … 284 258 for( i=0; i<info->fileCount; ++i ) 285 259 tr_fdFileClose( io->tor->destination, info->files[i].name ); 286 287 fastResumeSave( io->tor );288 260 } 289 261 } … … 297 269 tr_free( io ); 298 270 } 299 }300 301 302 /* try to load the fast resume file */303 int304 tr_ioLoadResume( tr_torrent_t * tor )305 {306 return tr_ioCheckFiles ( tor, TR_RECHECK_FAST );307 271 } 308 272 -
trunk/libtransmission/inout.h
r2315 r2462 28 28 typedef struct tr_io_s tr_io_t; 29 29 30 int tr_ioLoadResume( tr_torrent_t * );30 void tr_ioCheckFiles ( tr_torrent_t * ); 31 31 32 33 enum 34 { 35 TR_RECHECK_FAST, /* only try the fast resume, even if it's incomplete */ 36 TR_RECHECK_FORCE /* ignore the fast resume data; recheck from disk */ 37 }; 38 int tr_ioCheckFiles ( tr_torrent_t *, int recheckMode ); 39 40 41 tr_io_t * tr_ioInitFast ( tr_torrent_t * ); 32 tr_io_t * tr_ioNew ( tr_torrent_t * ); 42 33 43 34 /*********************************************************************** -
trunk/libtransmission/internal.h
r2444 r2462 98 98 #include "inout.h" 99 99 #include "ratecontrol.h" 100 #include "utils.h" 100 101 101 102 #ifndef TRUE … … 190 191 191 192 volatile char dieFlag; 192 volatile char recheckFlag;193 tr_bitfield_t * uncheckedPieces; 193 194 run_status_t runStatus; 194 195 cp_status_t cpStatus; -
trunk/libtransmission/torrent.c
r2454 r2462 181 181 { 182 182 int i; 183 uint64_t loaded; 183 184 char name[512]; 185 tr_bitfield_t * uncheckedPieces; 184 186 185 187 tor->info.flags |= flags; … … 232 234 tor->error = TR_OK; 233 235 tor->runStatus = flags & TR_FLAG_PAUSED ? TR_RUN_STOPPED : TR_RUN_RUNNING; 234 tor->recheckFlag = tr_ioCheckFiles( tor, TR_RECHECK_FAST ); 236 237 uncheckedPieces = tr_bitfieldNew( tor->info.pieceCount ); 238 loaded = tr_fastResumeLoad( tor, uncheckedPieces ); 239 if( tr_bitfieldIsEmpty( uncheckedPieces ) ) 240 tr_bitfieldFree( uncheckedPieces ); 241 else { 242 tor->uncheckedPieces = uncheckedPieces; 243 fprintf( stderr, "torrent %s has %d unchecked pieces\n", tor->info.name, (int)tr_bitfieldCountTrueBits(tor->uncheckedPieces) ); 244 } 245 246 247 if( !(loaded & TR_FR_SPEEDLIMIT ) ) { 248 int limit, enabled; 249 tr_getGlobalSpeedLimit( tor->handle, TR_UP, &enabled, &limit ); 250 tr_torrentSetSpeedLimit( tor, TR_UP, limit ); 251 tr_getGlobalSpeedLimit( tor->handle, TR_DOWN, &enabled, &limit ); 252 tr_torrentSetSpeedLimit( tor, TR_DOWN, limit ); 253 } 254 235 255 tor->cpStatus = tr_cpGetStatus( tor->completion ); 236 256 … … 445 465 #endif 446 466 447 void tr_torrentSetFolder( tr_torrent_t * tor, const char * path ) 467 static void 468 fastResumeSave( tr_torrent_t * tor ) 469 { 470 tr_fastResumeSave( tor ); 471 tor->fastResumeDirty = FALSE; 472 } 473 474 void 475 tr_torrentSetFolder( tr_torrent_t * tor, const char * path ) 448 476 { 449 477 tr_free( tor->destination ); 450 478 tor->destination = tr_strdup( path ); 451 452 if( !tor->ioLoaded ) 453 tor->ioLoaded = tr_ioLoadResume( tor ) == TR_OK; 454 } 455 456 const char* tr_torrentGetFolder( const tr_torrent_t * tor ) 479 fastResumeSave( tor ); 480 } 481 482 const char* 483 tr_torrentGetFolder( const tr_torrent_t * tor ) 457 484 { 458 485 return tor->destination; … … 583 610 584 611 585 if( tor-> recheckFlag)612 if( tor->uncheckedPieces ) 586 613 s->status = TR_STATUS_CHECK_WAIT; 587 614 else switch( tor->runStatus ) { … … 856 883 void tr_torrentRecheck( tr_torrent_t * tor ) 857 884 { 858 tor->recheckFlag = TRUE; 885 if( !tor->uncheckedPieces ) 886 tor->uncheckedPieces = tr_bitfieldNew( tor->info.pieceCount ); 887 tr_bitfieldAddRange( tor->uncheckedPieces, 0, tor->info.pieceCount ); 859 888 } 860 889 … … 998 1027 } 999 1028 tr_ioSync( tor->io ); 1029 fastResumeSave( tor ); 1000 1030 } 1001 1031 tr_torrentWriterUnlock( tor ); … … 1023 1053 if( tor->fastResumeDirty ) 1024 1054 { 1025 tor->fastResumeDirty = FALSE;1026 1055 fastResumeSave( tor ); 1027 1056 recheckCpState( tor ); … … 1039 1068 tr_ioClose( tor->io ); 1040 1069 tor->io = NULL; 1070 fastResumeSave( tor ); 1041 1071 1042 1072 /* close the peers */ … … 1079 1109 1080 1110 /* do we need to check files? */ 1081 if( tor-> recheckFlag)1111 if( tor->uncheckedPieces ) 1082 1112 { 1083 1113 if( !tr_lockTryLock( &checkFilesLock ) ) … … 1087 1117 tr_torrentWriterLock( tor ); 1088 1118 realStatus = tor->runStatus; 1089 tor->recheckFlag = FALSE;1090 1119 tor->runStatus = TR_RUN_CHECKING; 1091 1120 tr_torrentWriterUnlock( tor ); 1092 1121 1093 tr_ioCheckFiles( tor , TR_RECHECK_FORCE);1122 tr_ioCheckFiles( tor ); 1094 1123 setRunState( tor, realStatus ); 1095 1124 … … 1118 1147 *tor->errorString = '\0'; 1119 1148 tr_torrentResetTransferStats( tor ); 1120 tor->io = tr_ioInitFast( tor ); 1121 if( tor->io == NULL ) { 1122 tor->recheckFlag = TRUE; 1123 continue; 1124 } 1149 tor->io = tr_ioNew( tor ); 1125 1150 tr_peerIdNew ( tor->peer_id, sizeof(tor->peer_id) ); 1126 1151 tor->tracker = tr_trackerInit( tor );
Note: See TracChangeset
for help on using the changeset viewer.