Ignore:
Timestamp:
Mar 28, 2011, 4:31:05 PM (11 years ago)
Author:
jordan
Message:

(trunk libT) break the mac build and introduce new crashes.

This is partially to address #4145 "Downloads stuck at 100%" by refactoring the bitset, bitfield, and tr_completion; however, the ripple effect is larger than usual so things may get worse in the short term before getting better.

livings124: to fix the mac build, remove bitset.[ch] from xcode

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/peer-mgr.c

    r12229 r12248  
    375375    memset( peer, 0, sizeof( tr_peer ) );
    376376
    377     peer->have = TR_BITSET_INIT;
     377    peer->have = TR_BITFIELD_INIT;
    378378
    379379    tr_historyConstruct( &peer->blocksSentToClient,  CANCEL_HISTORY_SEC, ( RECHOKE_PERIOD_MSEC / 1000 ) );
     
    407407    {
    408408        peer = peerNew( atom );
     409        tr_bitfieldConstruct( &peer->have, torrent->tor->blockCount );
     410        tr_bitfieldConstruct( &peer->blame, torrent->tor->blockCount );
    409411        tr_ptrArrayInsertSorted( &torrent->peers, peer, peerCompare );
    410412    }
     
    420422    assert( peer != NULL );
    421423
    422     peerDeclinedAllRequests( tor->torrentPeers, peer );
     424    if( tor->torrentPeers->isRunning )
     425        peerDeclinedAllRequests( tor->torrentPeers, peer );
    423426
    424427    if( peer->msgs != NULL )
     
    426429
    427430    if( peer->io ) {
     431fprintf( stderr, "[%p] peer %p clearing/unreffing its io (%s:%d)\n", peer->io, peer, __FILE__, __LINE__ );
    428432        tr_peerIoClear( peer->io );
    429433        tr_peerIoUnref( peer->io ); /* balanced by the ref in handshakeDoneCB() */
     
    435439    tr_historyDestruct( &peer->cancelsSentToPeer   );
    436440
    437     tr_bitsetDestruct( &peer->have );
    438     tr_bitfieldFree( peer->blame );
     441    tr_bitfieldDestruct( &peer->have );
     442    tr_bitfieldDestruct( &peer->blame );
    439443    tr_free( peer->client );
    440444
     
    483487
    484488        for( peer_i=0; peer_i<peer_count; ++peer_i )
    485             if( tr_bitsetHas( &peers[peer_i]->have, piece_i ) )
     489            if( tr_bitfieldHas( &peers[peer_i]->have, piece_i ) )
    486490                ++r;
    487491
     
    867871}
    868872
     873static bool
     874testForEndgame( const Torrent * t )
     875{
     876    /* we consider ourselves to be in endgame if the number of bytes
     877       we've got requested is >= the number of bytes left to download */
     878    return ( t->requestCount * t->tor->blockSize )
     879               <= tr_cpLeftUntilDone( &t->tor->completion );
     880}
     881
    869882static void
    870883updateEndgame( Torrent * t )
    871884{
    872     const tr_torrent * tor = t->tor;
    873     const tr_block_index_t missing = tr_cpBlocksMissing( &tor->completion );
    874 
    875885    assert( t->requestCount >= 0 );
    876886
    877     if( (tr_block_index_t) t->requestCount < missing )
     887    if( !testForEndgame( t ) )
    878888    {
    879889        /* not in endgame */
     
    12681278 */
    12691279static void
    1270 tr_decrReplicationFromBitset( Torrent * t, const tr_bitset * bitset )
     1280tr_decrReplicationFromBitfield( Torrent * t, const tr_bitfield * b )
    12711281{
    12721282    int i;
     
    12761286    assert( t->pieceReplicationSize == t->tor->info.pieceCount );
    12771287
    1278     if( bitset->haveAll )
     1288    if( tr_bitfieldHasAll( b ) )
    12791289    {
    12801290        for( i=0; i<n; ++i )
    12811291            --t->pieceReplication[i];
    12821292    }
    1283     else if ( !bitset->haveNone )
    1284     {
    1285         const tr_bitfield * const b = &bitset->bitfield;
    1286 
     1293    else if ( !tr_bitfieldHasNone( b ) )
     1294    {
    12871295        for( i=0; i<n; ++i )
    12881296            if( tr_bitfieldHas( b, i ) )
     
    13171325    Torrent * t;
    13181326    struct weighted_piece * pieces;
    1319     const tr_bitset * have = &peer->have;
     1327    const tr_bitfield * const have = &peer->have;
    13201328
    13211329    /* sanity clause */
     
    13461354
    13471355        /* if the peer has this piece that we want... */
    1348         if( tr_bitsetHas( have, p->index ) )
     1356        if( tr_bitfieldHas( have, p->index ) )
    13491357        {
    13501358            tr_block_index_t b;
     
    22132221        {
    22142222            tr_peer * peer = peers[i];
    2215             if( tr_bitfieldHas( peer->blame, pieceIndex ) )
     2223            if( tr_bitfieldHas( &peer->blame, pieceIndex ) )
    22162224            {
    22172225                tordbg( t, "peer %s contributed to corrupt piece (%d); now has %d strikes",
     
    24032411stopTorrent( Torrent * t )
    24042412{
    2405     int i, n;
     2413    tr_peer * peer;
    24062414
    24072415    t->isRunning = false;
     
    24112419
    24122420    /* disconnect the peers. */
    2413     for( i=0, n=tr_ptrArraySize( &t->peers ); i<n; ++i )
    2414         peerDelete( t, tr_ptrArrayNth( &t->peers, i ) );
    2415     tr_ptrArrayClear( &t->peers );
     2421    while(( peer = tr_ptrArrayPop( &t->peers )))
     2422        peerDelete( t, peer );
    24162423
    24172424    /* disconnect the handshakes. handshakeAbort calls handshakeDoneCB(),
     
    24532460tr_peerUpdateProgress( tr_torrent * tor, tr_peer * peer )
    24542461{
    2455     const tr_bitset * have = &peer->have;
    2456 
    2457     if( have->haveAll )
     2462    const tr_bitfield * have = &peer->have;
     2463
     2464    if( tr_bitfieldHasAll( have ) )
    24582465    {
    24592466        peer->progress = 1.0;
    24602467    }
    2461     else if( have->haveNone )
     2468    else if( tr_bitfieldHasNone( have ) )
    24622469    {
    24632470        peer->progress = 0.0;
     
    24652472    else
    24662473    {
    2467         const float trueCount = tr_bitfieldCountTrueBits( &have->bitfield );
     2474        const float true_count = tr_bitfieldCountTrueBits( have );
    24682475
    24692476        if( tr_torrentHasMetadata( tor ) )
    2470             peer->progress = trueCount / tor->info.pieceCount;
     2477            peer->progress = true_count / tor->info.pieceCount;
    24712478        else /* without pieceCount, this result is only a best guess... */
    2472             peer->progress = trueCount / ( have->bitfield.bitCount + 1 );
     2479            peer->progress = true_count / ( have->bit_count + 1 );
    24732480    }
    24742481
     
    25172524                int j;
    25182525                for( j=0; j<peerCount; ++j )
    2519                     if( tr_bitsetHas( &peers[j]->have, piece ) )
     2526                    if( tr_bitfieldHas( &peers[j]->have, piece ) )
    25202527                        ++tab[i];
    25212528            }
     
    25242531}
    25252532
    2526 /* Returns the pieces that are available from peers */
    2527 tr_bitfield*
    2528 tr_peerMgrGetAvailable( const tr_torrent * tor )
    2529 {
    2530     int i;
    2531     Torrent * t = tor->torrentPeers;
    2532     const int peerCount = tr_ptrArraySize( &t->peers );
    2533     const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase( &t->peers );
    2534     tr_bitfield * pieces = tr_bitfieldNew( t->tor->info.pieceCount );
    2535 
    2536     assert( tr_torrentIsLocked( tor ) );
    2537 
    2538     for( i=0; i<peerCount; ++i )
    2539         tr_bitsetOr( pieces, &peers[i]->have );
    2540 
    2541     return pieces;
     2533static bool
     2534peerIsSeed( const tr_peer * peer )
     2535{
     2536    if( peer->progress >= 1.0 )
     2537        return true;
     2538
     2539    if( peer->atom && atomIsSeed( peer->atom ) )
     2540        return true;
     2541
     2542    return false;
     2543}
     2544
     2545/* count how many pieces we want that connected peers have */
     2546uint64_t
     2547tr_peerMgrGetDesiredAvailable( const tr_torrent * tor )
     2548{
     2549    size_t i;
     2550    size_t n;
     2551    uint64_t desiredAvailable;
     2552    const Torrent * t = tor->torrentPeers;
     2553
     2554    /* common shortcuts... */
     2555
     2556    if( tr_torrentIsSeed( t->tor ) )
     2557        return 0;
     2558
     2559    if( !tr_torrentHasMetadata( tor ) )
     2560        return 0;
     2561
     2562    n = tr_ptrArraySize( &t->peers );
     2563    if( n == 0 )
     2564        return 0;
     2565    else {
     2566        const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase( &t->peers );
     2567        for( i=0; i<n; ++i )
     2568            if( peers[i]->atom && atomIsSeed( peers[i]->atom ) )
     2569                return tr_cpLeftUntilDone( &tor->completion );
     2570    }
     2571
     2572    if( !t->pieceReplication || !t->pieceReplicationSize )
     2573        return 0;
     2574
     2575    /* do it the hard way */
     2576
     2577    desiredAvailable = 0;
     2578    for( i=0, n=tor->info.pieceCount; i<n; ++i )
     2579    {
     2580        if( tor->info.pieces[i].dnd )
     2581            continue;
     2582        if( t->pieceReplicationSize >= i )
     2583            continue;
     2584        if( t->pieceReplication[i] == 0 )
     2585            continue;
     2586
     2587        desiredAvailable += tr_cpMissingBytesInPiece( &t->tor->completion, i );
     2588    }
     2589
     2590    return desiredAvailable;
    25422591}
    25432592
     
    25452594tr_peerMgrTorrentStats( tr_torrent  * tor,
    25462595                        int         * setmePeersConnected,
    2547                         int         * setmeSeedsConnected,
    25482596                        int         * setmeWebseedsSendingToUs,
    25492597                        int         * setmePeersSendingToUs,
     
    25612609
    25622610    *setmePeersConnected       = 0;
    2563     *setmeSeedsConnected       = 0;
    25642611    *setmePeersGettingFromUs   = 0;
    25652612    *setmePeersSendingToUs     = 0;
     
    25862633        if( clientIsUploadingTo( peer ) )
    25872634            ++*setmePeersGettingFromUs;
    2588 
    2589         if( atomIsSeed( atom ) )
    2590             ++*setmeSeedsConnected;
    25912635    }
    25922636
     
    26242668{
    26252669    return peer->io ? tr_peerIoGetPieceSpeed_Bps( peer->io, now, direction ) : 0.0;
    2626 }
    2627 
    2628 static bool
    2629 peerIsSeed( const tr_peer * peer )
    2630 {
    2631     if( peer->progress >= 1.0 )
    2632         return true;
    2633 
    2634     if( peer->atom && atomIsSeed( peer->atom ) )
    2635         return true;
    2636 
    2637     return false;
    26382670}
    26392671
     
    27352767    return ( !tor->info.pieces[index].dnd ) /* we want it */
    27362768        && ( !tr_cpPieceIsComplete( &tor->completion, index ) )  /* we don't have it */
    2737         && ( tr_bitsetHas( &peer->have, index ) ); /* peer has it */
     2769        && ( tr_bitfieldHas( &peer->have, index ) ); /* peer has it */
    27382770}
    27392771
     
    32343266
    32353267    if( replicationExists( t ) )
    3236         tr_decrReplicationFromBitset( t, &peer->have );
     3268        tr_decrReplicationFromBitfield( t, &peer->have );
    32373269
    32383270    assert( removed == peer );
Note: See TracChangeset for help on using the changeset viewer.