Changeset 3 for trunk/libtransmission
- Timestamp:
- Jan 12, 2006, 6:29:20 PM (16 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 2 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/Jamfile
r1 r3 3 3 LIBTRANSMISSION_SRC = 4 4 transmission.c bencode.c net.c tracker.c peer.c inout.c 5 metainfo.c sha1.c utils.c upload.c fdlimit.c clients.c ; 5 metainfo.c sha1.c utils.c upload.c fdlimit.c clients.c 6 completion.c ; 6 7 7 8 Library libtransmission.a : $(LIBTRANSMISSION_SRC) ; -
trunk/libtransmission/fastresume.h
r2 r3 102 102 char * path; 103 103 int * fileMTimes; 104 int i;105 104 uint8_t * blockBitfield; 106 105 … … 131 130 132 131 /* Build and write the bitfield for blocks */ 133 blockBitfield = calloc( ( tor->blockCount + 7 ) / 8, 1 ); 134 for( i = 0; i < tor->blockCount; i++ ) 135 { 136 if( tor->blockHave[i] < 0 ) 137 { 138 tr_bitfieldAdd( blockBitfield, i ); 139 } 140 } 132 blockBitfield = tr_cpBlockBitfield( tor->completion ); 141 133 fwrite( blockBitfield, ( tor->blockCount + 7 ) / 8, 1, file ); 142 free( blockBitfield );143 134 144 135 /* Write the 'slotPiece' table */ … … 223 214 blockBitfield = calloc( ( tor->blockCount + 7 ) / 8, 1 ); 224 215 fread( blockBitfield, ( tor->blockCount + 7 ) / 8, 1, file ); 225 tor->blockHaveCount = 0; 226 for( i = 0; i < tor->blockCount; i++ ) 227 { 228 if( tr_bitfieldHas( blockBitfield, i ) ) 229 { 230 tor->blockHave[i] = -1; 231 (tor->blockHaveCount)++; 232 } 233 } 216 tr_cpBlockBitfieldSet( tor->completion, blockBitfield ); 234 217 free( blockBitfield ); 235 218 … … 254 237 } 255 238 } 256 257 for( j = tr_pieceStartBlock( i );258 j < tr_pieceStartBlock( i ) + tr_pieceCountBlocks( i );259 j++ )260 {261 if( tor->blockHave[j] > -1 )262 {263 break;264 }265 }266 if( j >= tr_pieceStartBlock( i ) + tr_pieceCountBlocks( i ) )267 {268 // tr_dbg( "Piece %d is complete", i );269 tr_bitfieldAdd( tor->bitfield, i );270 }271 239 } 272 240 // tr_dbg( "Slot used: %d", io->slotsUsed ); -
trunk/libtransmission/fdlimit.c
r1 r3 35 35 #define STATUS_UNUSED 2 36 36 #define STATUS_USED 4 37 #define STATUS_CLOSING 8 37 38 int status; 38 39 … … 112 113 !strcmp( path, f->open[i].path ) ) 113 114 { 115 if( f->open[i].status & STATUS_CLOSING ) 116 { 117 /* Wait until the file is closed */ 118 tr_lockUnlock( f->lock ); 119 tr_wait( 10 ); 120 tr_lockLock( f->lock ); 121 i = -1; 122 continue; 123 } 114 124 winner = i; 115 125 goto done; … … 135 145 for( i = 0; i < TR_MAX_OPEN_FILES; i++ ) 136 146 { 137 if( f->open[i].status & STATUS_USED)147 if( !( f->open[i].status & STATUS_UNUSED ) ) 138 148 { 139 149 continue; … … 148 158 if( winner >= 0 ) 149 159 { 160 /* Close the file: we mark it as closing then release the 161 lock while doing so, because fclose may take same time 162 and we don't want to block other threads */ 150 163 tr_dbg( "Closing %s", f->open[winner].path ); 164 f->open[winner].status = STATUS_CLOSING; 165 tr_lockUnlock( f->lock ); 151 166 fclose( f->open[winner].file ); 167 tr_lockLock( f->lock ); 152 168 goto open; 153 169 } -
trunk/libtransmission/inout.c
r1 r3 137 137 for( i = startBlock; i < endBlock; i++ ) 138 138 { 139 if( tor->blockHave[i] >= 0)139 if( !tr_cpBlockIsComplete( tor->completion, i ) ) 140 140 { 141 141 /* The piece is not complete */ … … 160 160 for( i = startBlock; i < endBlock; i++ ) 161 161 { 162 tor->blockHave[i] = 0; 163 tor->blockHaveCount -= 1; 162 tr_cpBlockRem( tor->completion, i ); 164 163 } 165 164 } … … 168 167 tr_inf( "Piece %d (slot %d): hash OK", index, 169 168 io->pieceSlot[index] ); 170 tr_ bitfieldAdd( tor->bitfield, index );169 tr_cpPieceAdd( tor->completion, index ); 171 170 } 172 171 … … 267 266 uint8_t * buf; 268 267 uint8_t hash[SHA_DIGEST_LENGTH]; 269 int startBlock, endBlock;270 268 271 269 io->pieceSlot = malloc( inf->pieceCount * sizeof( int ) ); … … 282 280 memset( io->pieceSlot, 0xFF, inf->pieceCount * sizeof( int ) ); 283 281 memset( io->slotPiece, 0xFF, inf->pieceCount * sizeof( int ) ); 284 memset( tor->bitfield, 0, ( inf->pieceCount + 7 ) / 8 );285 memset( tor->blockHave, 0, tor->blockCount );286 tor->blockHaveCount = 0;287 282 288 283 /* Check pieces */ … … 305 300 if( !memcmp( hash, &inf->pieces[20*j], SHA_DIGEST_LENGTH ) ) 306 301 { 307 int k;308 302 io->pieceSlot[j] = i; 309 303 io->slotPiece[i] = j; 310 tr_bitfieldAdd( tor->bitfield, j ); 311 312 startBlock = tr_pieceStartBlock( j ); 313 endBlock = startBlock + tr_pieceCountBlocks( j ); 314 for( k = startBlock; k < endBlock; k++ ) 315 { 316 tor->blockHave[k] = -1; 317 tor->blockHaveCount++; 318 } 304 305 tr_cpPieceAdd( tor->completion, j ); 319 306 break; 320 307 } … … 333 320 io->pieceSlot[inf->pieceCount - 1] = i; 334 321 io->slotPiece[i] = inf->pieceCount - 1; 335 tr_bitfieldAdd( tor->bitfield, inf->pieceCount - 1 ); 336 337 startBlock = tr_pieceStartBlock( inf->pieceCount - 1 ); 338 endBlock = startBlock + 339 tr_pieceCountBlocks( inf->pieceCount - 1 ); 340 for( j = startBlock; j < endBlock; j++ ) 341 { 342 tor->blockHave[j] = -1; 343 tor->blockHaveCount++; 344 } 322 323 tr_cpPieceAdd( tor->completion, inf->pieceCount - 1 ); 345 324 } 346 325 } … … 411 390 { 412 391 asprintf( &path, "%s/%s", tor->destination, inf->files[i].name ); 392 tr_lockUnlock( tor->lock ); 413 393 file = tr_fdFileOpen( tor->fdlimit, path ); 394 tr_lockLock( tor->lock ); 414 395 free( path ); 415 396 … … 422 403 (uint64_t) size ); 423 404 405 tr_lockUnlock( tor->lock ); 424 406 if( fseeko( file, posInFile, SEEK_SET ) ) 425 407 { 408 tr_lockLock( tor->lock ); 426 409 return 1; 427 410 } … … 430 413 if( fwrite( buf, willRead, 1, file ) != 1 ) 431 414 { 415 tr_lockLock( tor->lock ); 432 416 return 1; 433 417 } … … 437 421 if( fread( buf, willRead, 1, file ) != 1 ) 438 422 { 423 tr_lockLock( tor->lock ); 439 424 return 1; 440 425 } 441 426 } 442 427 tr_lockLock( tor->lock ); 443 428 tr_fdFileRelease( tor->fdlimit, file ); 444 429 -
trunk/libtransmission/internal.h
r2 r3 108 108 109 109 typedef struct tr_torrent_s tr_torrent_t; 110 typedef struct tr_completion_s tr_completion_t; 110 111 111 112 #include "bencode.h" … … 130 131 131 132 char * id; 133 char * key; 132 134 133 135 /* An escaped string used to include the hash in HTTP queries */ … … 143 145 int blockCount; 144 146 147 #if 0 145 148 /* Status for each block 146 149 -1 = we have it … … 149 152 int blockHaveCount; 150 153 uint8_t * bitfield; 154 #endif 155 tr_completion_t * completion; 151 156 152 157 volatile char die; … … 171 176 172 177 #include "utils.h" 178 #include "completion.h" 173 179 174 180 struct tr_handle_s … … 183 189 184 190 char id[21]; 191 char key[21]; 185 192 char prefsDirectory[256]; 186 193 }; -
trunk/libtransmission/peer.c
r2 r3 170 170 r = &peer->inRequests[j]; 171 171 block = tr_block( r->index,r->begin ); 172 if( tor->blockHave[block] > 0 ) 173 { 174 (tor->blockHave[block])--; 175 } 172 tr_cpDownloaderRem( tor->completion, block ); 176 173 } 177 174 if( !peer->amChoking ) … … 272 269 peer = tor->peers[i]; 273 270 274 /* Connect */ 275 if( ( peer->status & PEER_STATUS_IDLE ) && 276 !tr_fdSocketWillCreate( tor->fdlimit, 0 ) ) 277 { 278 peer->socket = tr_netOpen( peer->addr, peer->port ); 279 if( peer->socket < 0 ) 280 { 281 peer_dbg( "connection failed" ); 282 goto dropPeer; 283 } 284 peer->status = PEER_STATUS_CONNECTING; 285 } 286 287 /* Try to send handshake */ 288 if( peer->status & PEER_STATUS_CONNECTING ) 289 { 290 uint8_t buf[68]; 291 tr_info_t * inf = &tor->info; 292 293 buf[0] = 19; 294 memcpy( &buf[1], "BitTorrent protocol", 19 ); 295 memset( &buf[20], 0, 8 ); 296 memcpy( &buf[28], inf->hash, 20 ); 297 memcpy( &buf[48], tor->id, 20 ); 298 299 ret = tr_netSend( peer->socket, buf, 68 ); 271 if( peer->status < PEER_STATUS_HANDSHAKE ) 272 { 273 i++; 274 continue; 275 } 276 277 /* Try to read */ 278 for( ;; ) 279 { 280 if( peer->size < 1 ) 281 { 282 peer->size = 1024; 283 peer->buf = malloc( peer->size ); 284 } 285 else if( peer->pos >= peer->size ) 286 { 287 peer->size *= 2; 288 peer->buf = realloc( peer->buf, peer->size ); 289 } 290 ret = tr_netRecv( peer->socket, &peer->buf[peer->pos], 291 peer->size - peer->pos ); 300 292 if( ret & TR_NET_CLOSE ) 301 293 { … … 303 295 goto dropPeer; 304 296 } 305 else if( !( ret & TR_NET_BLOCK ) ) 306 { 307 peer_dbg( "SEND handshake" ); 308 peer->status = PEER_STATUS_HANDSHAKE; 309 } 310 } 311 312 /* Try to read */ 313 if( peer->status >= PEER_STATUS_HANDSHAKE ) 314 { 315 for( ;; ) 316 { 317 if( peer->size < 1 ) 318 { 319 peer->size = 1024; 320 peer->buf = malloc( peer->size ); 321 } 322 else if( peer->pos >= peer->size ) 323 { 324 peer->size *= 2; 325 peer->buf = realloc( peer->buf, peer->size ); 326 } 327 ret = tr_netRecv( peer->socket, &peer->buf[peer->pos], 328 peer->size - peer->pos ); 329 if( ret & TR_NET_CLOSE ) 330 { 331 peer_dbg( "connection closed" ); 332 goto dropPeer; 333 } 334 else if( ret & TR_NET_BLOCK ) 297 else if( ret & TR_NET_BLOCK ) 298 { 299 break; 300 } 301 peer->date = tr_date(); 302 peer->pos += ret; 303 if( parseBuf( tor, peer, ret ) ) 304 { 305 goto dropPeer; 306 } 307 } 308 309 if( peer->status < PEER_STATUS_CONNECTED ) 310 { 311 i++; 312 continue; 313 } 314 315 /* Try to write */ 316 writeBegin: 317 318 /* Send all smaller messages regardless of the upload cap */ 319 while( ( p = messagesPending( peer, &size ) ) ) 320 { 321 ret = tr_netSend( peer->socket, p, size ); 322 if( ret & TR_NET_CLOSE ) 323 { 324 goto dropPeer; 325 } 326 else if( ret & TR_NET_BLOCK ) 327 { 328 goto writeEnd; 329 } 330 messagesSent( peer, ret ); 331 } 332 333 /* Send pieces if we can */ 334 while( ( p = blockPending( tor, peer, &size ) ) ) 335 { 336 if( !tr_uploadCanUpload( tor->upload ) ) 337 { 338 break; 339 } 340 341 ret = tr_netSend( peer->socket, p, size ); 342 if( ret & TR_NET_CLOSE ) 343 { 344 goto dropPeer; 345 } 346 else if( ret & TR_NET_BLOCK ) 347 { 348 break; 349 } 350 351 blockSent( peer, ret ); 352 tr_uploadUploaded( tor->upload, ret ); 353 354 tor->uploaded[9] += ret; 355 peer->outTotal += ret; 356 peer->outDate = tr_date(); 357 358 /* In case this block is done, you may have messages 359 pending. Send them before we start the next block */ 360 goto writeBegin; 361 } 362 writeEnd: 363 364 /* Ask for a block whenever possible */ 365 if( !tr_cpIsSeeding( tor->completion ) && 366 !peer->amInterested && tor->peerCount > TR_MAX_PEER_COUNT - 2 ) 367 { 368 /* This peer is no use to us, and it seems there are 369 more */ 370 peer_dbg( "not interesting" ); 371 tr_peerRem( tor, i ); 372 continue; 373 } 374 375 if( peer->amInterested && !peer->peerChoking ) 376 { 377 int block; 378 while( peer->inRequestCount < OUR_REQUEST_COUNT ) 379 { 380 block = chooseBlock( tor, peer ); 381 if( block < 0 ) 335 382 { 336 383 break; 337 384 } 338 peer->date = tr_date(); 339 peer->pos += ret; 340 if( parseBuf( tor, peer, ret ) ) 341 { 342 goto dropPeer; 343 } 344 } 345 } 346 347 /* Try to write */ 348 writeBegin: 349 350 /* Send all smaller messages regardless of the upload cap */ 351 while( ( p = messagesPending( peer, &size ) ) ) 352 { 353 ret = tr_netSend( peer->socket, p, size ); 354 if( ret & TR_NET_CLOSE ) 355 { 356 goto dropPeer; 357 } 358 else if( ret & TR_NET_BLOCK ) 359 { 360 goto writeEnd; 361 } 362 messagesSent( peer, ret ); 363 } 364 365 /* Send pieces if we can */ 366 while( ( p = blockPending( tor, peer, &size ) ) ) 367 { 368 if( !tr_uploadCanUpload( tor->upload ) ) 369 { 370 break; 371 } 372 373 ret = tr_netSend( peer->socket, p, size ); 374 if( ret & TR_NET_CLOSE ) 375 { 376 goto dropPeer; 377 } 378 else if( ret & TR_NET_BLOCK ) 379 { 380 break; 381 } 382 383 blockSent( peer, ret ); 384 tr_uploadUploaded( tor->upload, ret ); 385 386 tor->uploaded[9] += ret; 387 peer->outTotal += ret; 388 peer->outDate = tr_date(); 389 390 /* In case this block is done, you may have messages 391 pending. Send them before we start the next block */ 392 goto writeBegin; 393 } 394 writeEnd: 395 396 /* Connected peers: ask for a block whenever possible */ 397 if( peer->status & PEER_STATUS_CONNECTED ) 398 { 399 if( tor->blockHaveCount < tor->blockCount && 400 !peer->amInterested && tor->peerCount > TR_MAX_PEER_COUNT - 2 ) 401 { 402 /* This peer is no use to us, and it seems there are 403 more */ 404 peer_dbg( "not interesting" ); 405 tr_peerRem( tor, i ); 406 continue; 407 } 408 409 if( peer->amInterested && !peer->peerChoking ) 410 { 411 int block; 412 while( peer->inRequestCount < OUR_REQUEST_COUNT ) 413 { 414 block = chooseBlock( tor, peer ); 415 if( block < 0 ) 416 { 417 break; 418 } 419 sendRequest( tor, peer, block ); 420 } 385 sendRequest( tor, peer, block ); 421 386 } 422 387 } -
trunk/libtransmission/peermessages.h
r2 r3 216 216 TR_HTONL( 1 + bitfieldSize, p ); 217 217 p[4] = 5; 218 memcpy( &p[5], t or->bitfield, bitfieldSize );218 memcpy( &p[5], tr_cpPieceBitfield( tor->completion ), bitfieldSize ); 219 219 220 220 peer_dbg( "SEND bitfield" ); … … 258 258 TR_HTONL( r->length, p + 13 ); 259 259 260 /* Remember that we have one more uploader for this block */ 261 (tor->blockHave[block])++; 260 tr_cpDownloaderAdd( tor->completion, block ); 262 261 263 262 peer_dbg( "SEND request %d/%d (%d bytes)", -
trunk/libtransmission/peerparse.h
r2 r3 52 52 { 53 53 r = &peer->inRequests[i]; 54 if( tor->blockHave[tr_block(r->index,r->begin)] > 0 ) 55 { 56 tor->blockHave[tr_block(r->index,r->begin)]--; 57 } 54 tr_cpDownloaderRem( tor->completion, tr_block(r->index,r->begin) ); 58 55 } 59 56 peer->inRequestCount = 0; … … 246 243 { 247 244 r = &peer->inRequests[j]; 248 if( tor->blockHave[tr_block(r->index,r->begin)] > 0 ) 249 { 250 tor->blockHave[tr_block(r->index,r->begin)]--; 251 } 245 tr_cpDownloaderRem( tor->completion, 246 tr_block(r->index,r->begin) ); 252 247 } 253 248 suckyClient = 1; … … 275 270 276 271 block = tr_block( r->index, r->begin ); 277 if( t or->blockHave[block] < 0)272 if( tr_cpBlockIsComplete( tor->completion, block ) ) 278 273 { 279 274 peer_dbg( "have this block already" ); … … 284 279 } 285 280 286 tor->blockHave[block] = -1; 287 tor->blockHaveCount += 1; 281 tr_cpBlockAdd( tor->completion, block ); 288 282 tr_ioWrite( tor->io, index, begin, len - 9, &p[8] ); 283 tr_cpDownloaderRem( tor->completion, block ); 289 284 290 285 sendCancel( tor, block ); 291 286 292 if( tr_ bitfieldHas( tor->bitfield, index ) )287 if( tr_cpPieceIsComplete( tor->completion, index ) ) 293 288 { 294 289 tr_peer_t * otherPeer; -
trunk/libtransmission/peerutils.h
r2 r3 164 164 } 165 165 166 /* Connect */ 167 if( ( peer->status & PEER_STATUS_IDLE ) && 168 !tr_fdSocketWillCreate( tor->fdlimit, 0 ) ) 169 { 170 peer->socket = tr_netOpen( peer->addr, peer->port ); 171 if( peer->socket < 0 ) 172 { 173 peer_dbg( "connection failed" ); 174 tr_fdSocketClosed( tor->fdlimit, 0 ); 175 return 1; 176 } 177 peer->status = PEER_STATUS_CONNECTING; 178 } 179 180 /* Try to send handshake */ 181 if( peer->status & PEER_STATUS_CONNECTING ) 182 { 183 uint8_t buf[68]; 184 tr_info_t * inf = &tor->info; 185 int ret; 186 187 buf[0] = 19; 188 memcpy( &buf[1], "BitTorrent protocol", 19 ); 189 memset( &buf[20], 0, 8 ); 190 memcpy( &buf[28], inf->hash, 20 ); 191 memcpy( &buf[48], tor->id, 20 ); 192 193 ret = tr_netSend( peer->socket, buf, 68 ); 194 if( ret & TR_NET_CLOSE ) 195 { 196 peer_dbg( "connection closed" ); 197 return 1; 198 } 199 else if( !( ret & TR_NET_BLOCK ) ) 200 { 201 peer_dbg( "SEND handshake" ); 202 peer->status = PEER_STATUS_HANDSHAKE; 203 } 204 } 205 166 206 return 0; 167 207 } … … 179 219 int i; 180 220 int bitfieldSize = ( inf->pieceCount + 7 ) / 8; 221 uint8_t * bitfield = tr_cpPieceBitfield( tor->completion ); 181 222 182 223 if( !peer->bitfield ) … … 188 229 for( i = 0; i < bitfieldSize; i++ ) 189 230 { 190 if( ( peer->bitfield[i] & ~( tor->bitfield[i]) ) & 0xFF )231 if( ( peer->bitfield[i] & ~(bitfield[i]) ) & 0xFF ) 191 232 { 192 233 return 1; … … 223 264 tr_info_t * inf = &tor->info; 224 265 225 int i, j; 226 int startBlock, endBlock, countBlocks; 266 int i; 227 267 int missingBlocks, minMissing; 228 268 int poolSize, * pool; … … 235 275 for( i = 0; i < inf->pieceCount; i++ ) 236 276 { 277 missingBlocks = tr_cpMissingBlocksForPiece( tor->completion, i ); 278 if( missingBlocks < 1 ) 279 { 280 /* We already have or are downloading all blocks */ 281 continue; 282 } 237 283 if( !tr_bitfieldHas( peer->bitfield, i ) ) 238 284 { 239 285 /* The peer doesn't have this piece */ 240 continue;241 }242 if( tr_bitfieldHas( tor->bitfield, i ) )243 {244 /* We already have it */245 continue;246 }247 248 /* Count how many blocks from this piece are missing */249 startBlock = tr_pieceStartBlock( i );250 countBlocks = tr_pieceCountBlocks( i );251 endBlock = startBlock + countBlocks;252 missingBlocks = countBlocks;253 for( j = startBlock; j < endBlock; j++ )254 {255 /* TODO: optimize */256 if( tor->blockHave[j] )257 {258 missingBlocks--;259 }260 if( missingBlocks > minMissing )261 {262 break;263 }264 }265 266 if( missingBlocks < 1 )267 {268 /* We are already downloading all blocks */269 286 continue; 270 287 } … … 332 349 333 350 /* Pick a block in this piece */ 334 startBlock = tr_pieceStartBlock( piece ); 335 endBlock = startBlock + tr_pieceCountBlocks( piece ); 336 for( i = startBlock; i < endBlock; i++ ) 337 { 338 if( !tor->blockHave[i] ) 339 { 340 block = i; 341 goto check; 342 } 343 } 344 351 block = tr_cpMissingBlockInPiece( tor->completion, piece ); 352 goto check; 353 } 354 355 free( pool ); 356 357 /* "End game" mode */ 358 minDownloading = 255; 359 block = -1; 360 for( i = 0; i < inf->pieceCount; i++ ) 361 { 362 int downloaders, block2; 363 if( !tr_bitfieldHas( peer->bitfield, i ) ) 364 { 365 /* The peer doesn't have this piece */ 366 continue; 367 } 368 if( tr_cpPieceIsComplete( tor->completion, i ) ) 369 { 370 /* We already have it */ 371 continue; 372 } 373 block2 = tr_cpMostMissingBlockInPiece( tor->completion, i, &downloaders ); 374 if( block2 > -1 && downloaders < minDownloading ) 375 { 376 block = block2; 377 minDownloading = downloaders; 378 } 379 } 380 381 check: 382 if( block < 0 ) 383 { 345 384 /* Shouldn't happen */ 346 385 return -1; 347 386 } 348 387 349 free( pool );350 351 /* "End game" mode */352 block = -1;353 minDownloading = TR_MAX_PEER_COUNT + 1;354 for( i = 0; i < tor->blockCount; i++ )355 {356 /* TODO: optimize */357 if( tr_bitfieldHas( peer->bitfield, tr_blockPiece( i ) ) &&358 tor->blockHave[i] >= 0 && tor->blockHave[i] < minDownloading )359 {360 block = i;361 minDownloading = tor->blockHave[i];362 }363 }364 365 if( block < 0 )366 {367 /* Shouldn't happen */368 return -1;369 }370 371 check:372 388 for( i = 0; i < peer->inRequestCount; i++ ) 373 389 { -
trunk/libtransmission/tracker.c
r1 r3 246 246 event = ""; 247 247 248 left = (uint64_t) ( tor->blockCount - tor->blockHaveCount ) * 249 (uint64_t) tor->blockSize; 250 left = MIN( left, inf->totalSize ); 248 left = tr_cpLeftBytes( tor->completion ); 251 249 252 250 ret = snprintf( (char *) tc->buf, tc->size, 253 "GET %s?info_hash=%s&peer_id=%s&port=%d&uploaded=%lld&" 254 "downloaded=%lld&left=%lld&compact=1&numwant=50%s " 255 "HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", 256 inf->trackerAnnounce, tor->hashString, tc->id, 257 tor->bindPort, tor->uploaded[9], tor->downloaded[9], 258 left, event, inf->trackerAddress ); 251 "GET %s?" 252 "info_hash=%s&" 253 "peer_id=%s&" 254 "port=%d&" 255 "uploaded=%lld&" 256 "downloaded=%lld&" 257 "left=%lld&" 258 "compact=1&" 259 "numwant=50&" 260 "key=%s" 261 "%s " 262 "HTTP/1.1\r\n" 263 "Host: %s\r\n" 264 "User-Agent: Transmission/%d.%d\r\n" 265 "Connection: close\r\n\r\n", 266 inf->trackerAnnounce, tor->hashString, tc->id, 267 tor->bindPort, tor->uploaded[9], tor->downloaded[9], 268 left, tor->key, event, inf->trackerAddress, 269 VERSION_MAJOR, VERSION_MINOR ); 259 270 260 271 ret = tr_netSend( tc->socket, tc->buf, ret ); … … 382 393 tc->leechers = beFoo->val.i; 383 394 } 384 if( tc->seeders + tc-> seeders >= 50 )395 if( tc->seeders + tc->leechers >= 50 ) 385 396 { 386 397 tc->hasManyPeers = 1; -
trunk/libtransmission/transmission.c
r2 r3 52 52 } 53 53 54 /* Random key */ 55 for( i = 0; i < 20; i++ ) 56 { 57 r = tr_rand( 36 ); 58 h->key[i] = ( r < 26 ) ? ( 'a' + r ) : ( '0' + r - 26 ) ; 59 } 60 54 61 /* Don't exit when writing on a broken socket */ 55 62 signal( SIGPIPE, SIG_IGN ); … … 165 172 tor->status = TR_STATUS_PAUSE; 166 173 tor->id = h->id; 174 tor->key = h->key; 167 175 168 176 /* Guess scrape URL */ … … 192 200 tor->blockCount = ( inf->totalSize + tor->blockSize - 1 ) / 193 201 tor->blockSize; 194 tor->blockHave = calloc( tor->blockCount, 1 ); 195 tor->bitfield = calloc( ( inf->pieceCount + 7 ) / 8, 1 ); 202 tor->completion = tr_cpInit( tor ); 196 203 197 204 tr_lockInit( &tor->lock ); … … 331 338 inf = &tor->info; 332 339 333 tr_lockLock( tor->lock );334 335 340 if( ( tor->status & TR_STATUS_STOPPED ) || 336 341 ( ( tor->status & TR_STATUS_STOPPING ) && … … 340 345 tor->status = TR_STATUS_PAUSE; 341 346 } 347 348 tr_lockLock( tor->lock ); 342 349 343 350 memcpy( &s[i].info, &tor->info, sizeof( tr_info_t ) ); … … 365 372 } 366 373 367 s[i].progress = (float) tor->blockHaveCount / (float) tor->blockCount; 368 374 s[i].progress = tr_cpCompletionAsFloat( tor->completion ); 369 375 s[i].rateDownload = rateDownload( tor ); 370 376 s[i].rateUpload = rateUpload( tor ); … … 376 382 else 377 383 { 378 s[i].eta = (float) ( tor->blockCount - tor->blockHaveCount) *379 (float) tor->blockSize / s[i].rateDownload / 1024.0;384 s[i].eta = (float) ( 1.0 - s[i].progress ) * 385 (float) inf->totalSize / s[i].rateDownload / 1024.0; 380 386 if( s[i].eta > 99 * 3600 + 59 * 60 + 59 ) 381 387 { … … 388 394 piece = j * inf->pieceCount / 120; 389 395 390 if( tr_ bitfieldHas( tor->bitfield, piece ) )396 if( tr_cpPieceIsComplete( tor->completion, piece ) ) 391 397 { 392 398 s[i].pieces[j] = -1; … … 431 437 { 432 438 /* Join the thread first */ 433 tr_lockLock( tor->lock );434 439 torrentReallyStop( h, t ); 435 tr_lockUnlock( tor->lock );436 440 } 437 441 … … 439 443 440 444 tr_lockClose( tor->lock ); 445 tr_cpClose( tor->completion ); 441 446 442 447 if( tor->destination ) … … 446 451 free( inf->pieces ); 447 452 free( inf->files ); 448 free( tor->blockHave );449 free( tor->bitfield );450 453 free( tor ); 451 454 … … 477 480 #endif 478 481 482 tr_lockLock( tor->lock ); 483 479 484 tor->io = tr_ioInit( tor ); 480 tor->status = ( tor->blockHaveCount < tor->blockCount) ?481 TR_STATUS_ DOWNLOAD : TR_STATUS_SEED;482 485 tor->status = tr_cpIsSeeding( tor->completion ) ? 486 TR_STATUS_SEED : TR_STATUS_DOWNLOAD; 487 483 488 while( !tor->die ) 484 489 { 485 490 date1 = tr_date(); 486 487 tr_lockLock( tor->lock );488 491 489 492 /* Are we finished ? */ 490 493 if( ( tor->status & TR_STATUS_DOWNLOAD ) && 491 t or->blockHaveCount >= tor->blockCount)494 tr_cpIsSeeding( tor->completion ) ) 492 495 { 493 496 /* Done */ … … 502 505 tr_trackerPulse( tor->tracker ); 503 506 504 tr_lockUnlock( tor->lock );505 506 507 if( tor->status & TR_STATUS_STOPPED ) 507 508 { … … 513 514 if( date2 < date1 + 20 ) 514 515 { 516 tr_lockUnlock( tor->lock ); 515 517 tr_wait( date1 + 20 - date2 ); 516 } 517 } 518 tr_lockLock( tor->lock ); 519 } 520 } 521 522 tr_lockUnlock( tor->lock ); 518 523 519 524 tr_ioClose( tor->io ); -
trunk/libtransmission/utils.h
r1 r3 76 76 } 77 77 78 static inline void tr_bitfieldRem( uint8_t * bitfield, int piece ) 79 { 80 bitfield[ piece / 8 ] &= ~( 1 << ( 7 - ( piece % 8 ) ) ); 81 } 82 78 83 #define tr_blockPiece(a) _tr_blockPiece(tor,a) 79 84 static inline int _tr_blockPiece( tr_torrent_t * tor, int block )
Note: See TracChangeset
for help on using the changeset viewer.