Changeset 2064


Ignore:
Timestamp:
Jun 13, 2007, 8:38:42 AM (15 years ago)
Author:
charles
Message:

Attempt fixing the partial download seed problem.

We need to not tell trackers that we're seeders when we're not, so I've
added a new tr_torrent state TR_STATE_DONE (see transmission.h:489)
to indicate we're not seeders, but we're not asking for anything either.
The GTK client draws SEED as "Seeding; Uploading to X of Y peers"

and DONE as "Uploading to X of Y peers".

Location:
branches/file_selection
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • branches/file_selection/gtk/actions.c

    r2054 r2064  
    7878  { "start-torrent", GTK_STOCK_EXECUTE,
    7979    N_("_Start"), "<control>S", NULL, G_CALLBACK(action_cb) },
     80  { "recheck-torrent", GTK_STOCK_REFRESH,
     81    N_("Re_check"), NULL, NULL, G_CALLBACK(action_cb) },
    8082  { "stop-torrent", GTK_STOCK_STOP,
    8183    N_("S_top"), "<control>T", NULL, G_CALLBACK(action_cb) },
  • branches/file_selection/gtk/main.c

    r2057 r2064  
    941941}
    942942
     943static void
     944recheckTorrentForeach (GtkTreeModel * model,
     945                       GtkTreePath  * path UNUSED,
     946                       GtkTreeIter  * iter,
     947                       gpointer       data UNUSED)
     948{
     949    TrTorrent * gtor = NULL;
     950    int status = 0;
     951    tr_torrent_t * tor;
     952    gtk_tree_model_get( model, iter, MC_TORRENT, &gtor, MC_STAT, &status, -1 );
     953    tor = tr_torrent_handle( gtor );
     954    if( status & TR_STATUS_ACTIVE )
     955        tr_torrentStop( tor );
     956    tr_torrentRemoveFastResume( tor );
     957    tr_torrentStart( tor );
     958    g_object_unref( G_OBJECT( gtor ) );
     959}
     960
    943961void
    944962doAction ( const char * action_name, gpointer user_data )
     
    961979        GtkTreeSelection * s = tr_window_get_selection(data->wind);
    962980        gtk_tree_selection_selected_foreach( s, stopTorrentForeach, NULL );
     981        changed |= gtk_tree_selection_count_selected_rows( s ) != 0;
     982    }
     983    else if (!strcmp (action_name, "recheck-torrent"))
     984    {
     985        GtkTreeSelection * s = tr_window_get_selection(data->wind);
     986        gtk_tree_selection_selected_foreach( s, recheckTorrentForeach, NULL );
    963987        changed |= gtk_tree_selection_count_selected_rows( s ) != 0;
    964988    }
  • branches/file_selection/gtk/tr_torrent.c

    r1998 r2064  
    673673        }
    674674    }
    675     else if(TR_STATUS_SEED & status)
     675    else if( TR_STATUS_SEED & status )
    676676    {
    677677        top = g_strdup_printf(
     
    680680            upeers, tpeers );
    681681    }
     682    else if( TR_STATUS_DONE & status )
     683    {
     684        top = g_strdup_printf(
     685            ngettext( "Uploading to %d of %d peer",
     686                      "Uploading to %d of %d peers", tpeers ),
     687            upeers, tpeers );
     688    }
    682689    else if( TR_STATUS_STOPPING & status )
    683690    {
  • branches/file_selection/gtk/ui.h

    r2054 r2064  
    66"      <menuitem action='start-torrent'/>\n"
    77"      <menuitem action='stop-torrent'/>\n"
     8"      <menuitem action='recheck-torrent'/>\n"
    89"      <menuitem action='remove-torrent'/>\n"
    910"      <separator/>\n"
     
    3637"    <menuitem action='start-torrent'/>\n"
    3738"    <menuitem action='stop-torrent'/>\n"
     39"    <menuitem action='recheck-torrent'/>\n"
    3840"    <separator/>\n"
    3941"    <menuitem action='remove-torrent'/>\n"
  • branches/file_selection/libtransmission/completion.c

    r2005 r2064  
    2424
    2525#include "transmission.h"
     26#include "completion.h"
     27
     28struct tr_completion_s
     29{
     30    tr_torrent_t      * tor;
     31    tr_bitfield_t     * blockBitfield;
     32    uint8_t           * blockDownloaders;
     33    tr_bitfield_t     * pieceBitfield;
     34
     35    /* a block is missing if we don't have it AND there's not a request pending */
     36    int * missingBlocks;
     37
     38    /* a block is complete if and only if we have it */
     39    int * completeBlocks;
     40};
    2641
    2742tr_completion_t * tr_cpInit( tr_torrent_t * tor )
     
    3550    cp->pieceBitfield    = tr_bitfieldNew( tor->info.pieceCount );
    3651    cp->missingBlocks    = malloc( tor->info.pieceCount * sizeof( int ) );
     52    cp->completeBlocks   = malloc( tor->info.pieceCount * sizeof( int ) );
    3753
    3854    tr_cpReset( cp );
     
    4763    tr_bitfieldFree( cp->pieceBitfield );
    4864    free(            cp->missingBlocks );
     65    free(            cp->completeBlocks );
    4966    free(            cp );
    5067}
     
    5572    int i;
    5673
    57     cp->blockCount = 0;
    5874    tr_bitfieldClear( cp->blockBitfield );
    5975    memset( cp->blockDownloaders, 0, tor->blockCount );
    6076    tr_bitfieldClear( cp->pieceBitfield );
    61     for( i = 0; i < tor->info.pieceCount; i++ )
    62     {
     77    for( i = 0; i < tor->info.pieceCount; ++i ) {
    6378        cp->missingBlocks[i] = tr_pieceCountBlocks( i );
    64     }
    65 }
    66 
    67 float tr_cpCompletionAsFloat( tr_completion_t * cp )
    68 {
    69     return (float) cp->blockCount / (float) cp->tor->blockCount;
    70 }
    71 
    72 uint64_t tr_cpLeftBytes( tr_completion_t * cp )
    73 {
    74     tr_torrent_t * tor = cp->tor;
    75     uint64_t left;
    76     left = (uint64_t) ( cp->tor->blockCount - cp->blockCount ) *
    77            (uint64_t) tor->blockSize;
    78     if( !tr_bitfieldHas( cp->blockBitfield, cp->tor->blockCount - 1 ) &&
    79         tor->info.totalSize % tor->blockSize )
    80     {
    81         left += tor->info.totalSize % tor->blockSize;
    82         left -= tor->blockSize;
    83     }
    84     return left;
    85 }
    86 
    87 /* Pieces */
    88 int tr_cpPieceHasAllBlocks( tr_completion_t * cp, int piece )
    89 {
    90     tr_torrent_t * tor = cp->tor;
    91     int startBlock  = tr_pieceStartBlock( piece );
    92     int endBlock    = startBlock + tr_pieceCountBlocks( piece );
    93     int i;
    94 
    95     for( i = startBlock; i < endBlock; i++ )
    96     {
    97         if( !tr_bitfieldHas( cp->blockBitfield, i ) )
    98         {
    99             return 0;
    100         }
    101     }   
    102     return 1;
    103 }
    104 int tr_cpPieceIsComplete( tr_completion_t * cp, int piece )
    105 {
    106     return tr_bitfieldHas( cp->pieceBitfield, piece );
    107 }
    108 
    109 tr_bitfield_t * tr_cpPieceBitfield( tr_completion_t * cp )
     79        cp->completeBlocks[i] = 0;
     80    }
     81}
     82
     83int tr_cpPieceHasAllBlocks( const tr_completion_t * cp, int piece )
     84{
     85    return tr_cpPieceIsComplete( cp, piece );
     86}
     87
     88int tr_cpPieceIsComplete( const tr_completion_t * cp, int piece )
     89{
     90    const int total = _tr_pieceCountBlocks( cp->tor, piece );
     91    const int have = cp->completeBlocks[piece];
     92    assert( have <= total );
     93    return have == total;
     94}
     95
     96const tr_bitfield_t * tr_cpPieceBitfield( const tr_completion_t * cp )
    11097{
    11198    return cp->pieceBitfield;
     
    114101void tr_cpPieceAdd( tr_completion_t * cp, int piece )
    115102{
    116     tr_torrent_t * tor = cp->tor;
    117     int startBlock, endBlock, i;
    118 
    119     startBlock = tr_pieceStartBlock( piece );
    120     endBlock   = startBlock + tr_pieceCountBlocks( piece );
    121     for( i = startBlock; i < endBlock; i++ )
    122     {
    123         tr_cpBlockAdd( cp, i );
    124     }
     103    int i;
     104    const tr_torrent_t * tor = cp->tor;
     105    const int n_blocks = tr_pieceCountBlocks( piece );
     106    const int startBlock = tr_pieceStartBlock( piece );
     107    const int endBlock   = startBlock + tr_pieceCountBlocks( piece );
     108
     109    cp->completeBlocks[piece] = n_blocks;
     110
     111    for( i=startBlock; i<endBlock; ++i )
     112        if( !cp->blockDownloaders[i] )
     113            --cp->missingBlocks[piece];
     114
     115    tr_bitfieldAddRange( cp->blockBitfield, startBlock, endBlock-1 );
    125116
    126117    tr_bitfieldAdd( cp->pieceBitfield, piece );
     
    129120void tr_cpPieceRem( tr_completion_t * cp, int piece )
    130121{
    131     tr_torrent_t * tor = cp->tor;
    132     int startBlock, endBlock, i;
    133 
    134     startBlock = tr_pieceStartBlock( piece );
    135     endBlock   = startBlock + tr_pieceCountBlocks( piece );
    136     for( i = startBlock; i < endBlock; i++ )
    137     {
    138         tr_cpBlockRem( cp, i );
    139     }
     122    int i;
     123    const tr_torrent_t * tor = cp->tor;
     124    const int n_blocks = tr_pieceCountBlocks( piece );
     125    const int startBlock = tr_pieceStartBlock( piece );
     126    const int endBlock   = startBlock + n_blocks;
     127
     128    cp->completeBlocks[piece] = 0;
     129
     130    for( i=startBlock; i<endBlock; ++i )
     131        if( !cp->blockDownloaders[i] )
     132            ++cp->missingBlocks[piece];
     133
     134    tr_bitfieldRemRange ( cp->blockBitfield, startBlock, endBlock-1 );
    140135
    141136    tr_bitfieldRem( cp->pieceBitfield, piece );
     
    170165void tr_cpBlockAdd( tr_completion_t * cp, int block )
    171166{
    172     tr_torrent_t * tor = cp->tor;
     167    const tr_torrent_t * tor = cp->tor;
     168
    173169    if( !tr_cpBlockIsComplete( cp, block ) )
    174170    {
    175         (cp->blockCount)++;
     171        const int piece = tr_blockPiece( block );
     172        ++cp->completeBlocks[piece];
     173
     174        if( cp->completeBlocks[piece] == tr_pieceCountBlocks( piece ) )
     175            tr_bitfieldAdd( cp->pieceBitfield, piece );
     176
    176177        if( !cp->blockDownloaders[block] )
    177         {
    178             (cp->missingBlocks[tr_blockPiece(block)])--;
    179         }
    180     }
    181     tr_bitfieldAdd( cp->blockBitfield, block );
    182 }
    183 
    184 void tr_cpBlockRem( tr_completion_t * cp, int block )
    185 {
    186     tr_torrent_t * tor = cp->tor;
    187     if( tr_cpBlockIsComplete( cp, block ) )
    188     {
    189         (cp->blockCount)--;
    190         if( !cp->blockDownloaders[block] )
    191         {
    192             (cp->missingBlocks[tr_blockPiece(block)])++;
    193         }
    194     }
    195     tr_bitfieldRem( cp->blockBitfield, block );
    196 }
    197 
    198 tr_bitfield_t * tr_cpBlockBitfield( tr_completion_t * cp )
     178            cp->missingBlocks[piece]--;
     179
     180        tr_bitfieldAdd( cp->blockBitfield, block );
     181    }
     182}
     183
     184const tr_bitfield_t * tr_cpBlockBitfield( const tr_completion_t * cp )
    199185{
    200186    return cp->blockBitfield;
    201187}
    202188
    203 void tr_cpBlockBitfieldSet( tr_completion_t * cp, tr_bitfield_t * bitfield )
    204 {
    205     tr_torrent_t * tor = cp->tor;
    206     int i, j;
    207     int startBlock, endBlock;
    208     int pieceComplete;
    209 
    210     for( i = 0; i < cp->tor->info.pieceCount; i++ )
    211     {
    212         startBlock    = tr_pieceStartBlock( i );
    213         endBlock      = startBlock + tr_pieceCountBlocks( i );
    214         pieceComplete = 1;
    215 
    216         for( j = startBlock; j < endBlock; j++ )
    217         {
    218             if( tr_bitfieldHas( bitfield, j ) )
    219             {
    220                 tr_cpBlockAdd( cp, j );
    221             }
    222             else
    223             {
    224                 pieceComplete = 0;
    225             }
    226         }
    227         if( pieceComplete )
    228         {
    229             tr_cpPieceAdd( cp, i );
    230         }
    231     }
    232 }
    233 
    234 float tr_cpPercentBlocksInPiece( tr_completion_t * cp, int piece )
    235 {
    236     tr_torrent_t * tor = cp->tor;
    237     int i;
    238     int blockCount, startBlock, endBlock;
    239     int complete;
    240     tr_bitfield_t * bitfield;
    241    
    242     blockCount  = tr_pieceCountBlocks( piece );
    243     startBlock  = tr_pieceStartBlock( piece );
    244     endBlock    = startBlock + blockCount;
    245     complete    = 0;
    246    
    247     bitfield = cp->blockBitfield;
    248 
    249     for( i = startBlock; i < endBlock; i++ )
    250     {
     189void
     190tr_cpBlockBitfieldSet( tr_completion_t * cp, tr_bitfield_t * bitfield )
     191{
     192    int i;
     193    tr_torrent_t * tor = cp->tor;
     194
     195    tr_cpReset( cp );
     196    cp->tor = tor;
     197
     198    for( i=0; i < cp->tor->blockCount; ++i )
    251199        if( tr_bitfieldHas( bitfield, i ) )
    252         {
    253             complete++;
    254         }
    255     }   
    256 
    257     return (float)complete / (float)blockCount;
     200            tr_cpBlockAdd( cp, i );
     201}
     202
     203float tr_cpPercentBlocksInPiece( const tr_completion_t * cp, int piece )
     204{
     205    return cp->completeBlocks[piece] / (double)_tr_pieceCountBlocks( cp->tor, piece );
    258206}
    259207
     
    279227}
    280228
    281 int tr_cpMostMissingBlockInPiece( tr_completion_t * cp, int piece,
    282                                   int * downloaders )
     229int tr_cpMostMissingBlockInPiece( const tr_completion_t * cp,
     230                                  int                     piece,
     231                                  int                   * downloaders )
    283232{
    284233    tr_torrent_t * tor = cp->tor;
     
    325274}
    326275
     276
     277int
     278tr_cpMissingBlocksForPiece( const tr_completion_t * cp, int piece )
     279{
     280    return cp->missingBlocks[piece];
     281}
     282
     283/***
     284****
     285***/
     286
     287/* returns one of CP_COMPLETE, CP_DONE, or CP_INCOMPLETE */
     288int
     289tr_cpGetState ( const tr_completion_t * cp )
     290{
     291    int i;
     292    int ret = CP_COMPLETE;
     293    const tr_info_t * info = &cp->tor->info;
     294
     295    for( i=0; i<info->pieceCount; ++i ) {
     296        if( tr_cpPieceIsComplete( cp, i ) )
     297            continue;
     298        if( info->pieces[i].priority != TR_PRI_DND)
     299            return CP_INCOMPLETE;
     300        ret = CP_DONE;
     301    }
     302
     303    return ret;
     304}
     305
     306uint64_t
     307tr_cpLeftBytes( const tr_completion_t * cp, int state )
     308{
     309    int i;
     310    uint64_t ret = 0;
     311    const tr_torrent_t * tor = cp->tor;
     312    const tr_info_t * info = &tor->info;
     313
     314    assert( cp!=NULL );
     315    assert( tor!=NULL );
     316    assert( state==CP_DONE || state==CP_COMPLETE );
     317
     318    for( i=0; i<info->pieceCount; ++i ) {
     319        if( tr_cpPieceIsComplete( cp, i ) )
     320            continue;
     321        if( state==CP_DONE && info->pieces[i].priority==TR_PRI_DND )
     322            continue;
     323        ret += tor->blockSize * (tr_pieceCountBlocks(i) - cp->completeBlocks[i]);
     324    }
     325
     326    return ret;
     327}
     328
     329float
     330tr_cpCompletionAsFloat( const tr_completion_t * cp, int state )
     331{
     332    int i;
     333    int have = 0;
     334    int total = 0;
     335    const tr_torrent_t * tor = cp->tor;
     336
     337    assert( cp!=NULL );
     338    assert( tor!=NULL );
     339    assert( state==CP_DONE || state==CP_COMPLETE );
     340
     341    for( i=0; i<tor->info.pieceCount; ++i ) {
     342        const int n_blocks = tr_pieceCountBlocks(i);
     343        if( tr_cpPieceIsComplete( cp, i ) ) {
     344            have += n_blocks;
     345            total += n_blocks;
     346            continue;
     347        }
     348        if( state==CP_DONE && tor->info.pieces[i].priority==TR_PRI_DND )
     349            continue;
     350
     351        have += cp->completeBlocks[i];
     352        total += n_blocks;
     353    }
     354
     355    return !total ? 0.0f : (float)have / (float)total;
     356}
  • branches/file_selection/libtransmission/completion.h

    r2005 r2064  
    2323 *****************************************************************************/
    2424
    25 struct tr_completion_s
    26 {
    27     tr_torrent_t      * tor;
    28     tr_bitfield_t     * blockBitfield;
    29     uint8_t           * blockDownloaders;
    30     int                 blockCount;
    31     tr_bitfield_t     * pieceBitfield;
    32     int               * missingBlocks;
     25#ifndef TR_COMPLETION_H
     26#define TR_COMPLETION_H
     27
     28#include "transmission.h"
     29
     30tr_completion_t     * tr_cpInit( tr_torrent_t * );
     31void                  tr_cpClose( tr_completion_t * );
     32void                  tr_cpReset( tr_completion_t * );
     33
     34/* General */
     35
     36enum {
     37  CP_COMPLETE,    /* has every piece */
     38  CP_DONE,        /* has all the pieces but the DND ones */
     39  CP_INCOMPLETE   /* doesn't have all the desired pieces */
    3340};
    3441
    35 tr_completion_t * tr_cpInit( tr_torrent_t * );
    36 void              tr_cpClose( tr_completion_t * );
    37 void              tr_cpReset( tr_completion_t * );
     42/* returns one of CP_SEEDING, CP_DONE, or CP_INCOMPLETE */
     43int tr_cpGetState ( const tr_completion_t * );
    3844
    39 /* General */
    40 float             tr_cpCompletionAsFloat( tr_completion_t * );
    41 static inline int tr_cpIsSeeding( tr_completion_t * cp )
    42 {
    43     return ( cp->blockCount == cp->tor->blockCount );
    44 }
    45 uint64_t          tr_cpLeftBytes( tr_completion_t * );
     45/* pass in CP_COMPLETE to see how many total bytes left,
     46   or CP_DONE to see how many left until you're done */
     47uint64_t              tr_cpLeftBytes( const tr_completion_t *, int state );
     48
     49/* pass in CP_COMPLETE to see what percent of the total is complete,
     50   or CP_DONE to see what percent of the desired blocks are done */
     51float                 tr_cpCompletionAsFloat( const tr_completion_t *, int state );
    4652
    4753/* Pieces */
    48 int               tr_cpPieceHasAllBlocks( tr_completion_t *, int piece );
    49 int               tr_cpPieceIsComplete( tr_completion_t *, int piece );
    50 tr_bitfield_t   * tr_cpPieceBitfield( tr_completion_t * );
    51 void              tr_cpPieceAdd( tr_completion_t *, int piece );
    52 void              tr_cpPieceRem( tr_completion_t *, int piece );
     54int                   tr_cpPieceHasAllBlocks( const tr_completion_t *, int piece );
     55int                   tr_cpPieceIsComplete( const tr_completion_t *, int piece );
     56const tr_bitfield_t * tr_cpPieceBitfield( const tr_completion_t* );
     57void                  tr_cpPieceAdd( tr_completion_t *, int piece );
     58void                  tr_cpPieceRem( tr_completion_t *, int piece );
    5359
    5460/* Blocks */
    55 void              tr_cpDownloaderAdd( tr_completion_t *, int block );
    56 void              tr_cpDownloaderRem( tr_completion_t *, int block );
    57 int               tr_cpBlockIsComplete( const tr_completion_t *, int block );
    58 void              tr_cpBlockAdd( tr_completion_t *, int block );
    59 void              tr_cpBlockRem( tr_completion_t *, int block );
    60 tr_bitfield_t   * tr_cpBlockBitfield( tr_completion_t * );
    61 void              tr_cpBlockBitfieldSet( tr_completion_t *, tr_bitfield_t * );
    62 float             tr_cpPercentBlocksInPiece( tr_completion_t * cp, int piece );
     61void                  tr_cpDownloaderAdd( tr_completion_t *, int block );
     62void                  tr_cpDownloaderRem( tr_completion_t *, int block );
     63int                   tr_cpBlockIsComplete( const tr_completion_t *, int block );
     64void                  tr_cpBlockAdd( tr_completion_t *, int block );
     65const tr_bitfield_t * tr_cpBlockBitfield( const tr_completion_t * );
     66void                  tr_cpBlockBitfieldSet( tr_completion_t *, tr_bitfield_t * );
     67float                 tr_cpPercentBlocksInPiece( const tr_completion_t * cp, int piece );
    6368/* Missing = we don't have it and we are not getting it from any peer yet */
    64 static inline int tr_cpMissingBlocksForPiece( const tr_completion_t * cp, int piece )
    65 {
    66     return cp->missingBlocks[piece];
    67 }
    68 int               tr_cpMissingBlockInPiece( const tr_completion_t *, int piece );
    69 int               tr_cpMostMissingBlockInPiece( tr_completion_t *, int piece,
    70                                                 int * downloaders );
     69int                   tr_cpMissingBlocksForPiece( const tr_completion_t * cp, int piece );
     70int                   tr_cpMissingBlockInPiece( const tr_completion_t *, int piece );
     71int                   tr_cpMostMissingBlockInPiece( const tr_completion_t *, int piece,
     72                                                    int * downloaders );
     73
     74#endif
  • branches/file_selection/libtransmission/peer.c

    r2005 r2064  
    554554
    555555    /* Ask for a block whenever possible */
    556     if( !tr_cpIsSeeding( tor->completion ) &&
    557         !peer->amInterested && tor->peerCount > TR_MAX_PEER_COUNT - 2 )
     556    if( tr_cpGetState( tor->completion ) == CP_INCOMPLETE
     557        && !peer->amInterested
     558        && tor->peerCount > TR_MAX_PEER_COUNT - 2 )
    558559    {
    559560        /* This peer is no use to us, and it seems there are
  • branches/file_selection/libtransmission/peermessages.h

    r1727 r2064  
    286286static void sendBitfield( tr_torrent_t * tor, tr_peer_t * peer )
    287287{
    288     uint8_t       * p;
    289     tr_bitfield_t * bitfield;
     288    uint8_t             * p;
     289    const tr_bitfield_t * bitfield;
    290290
    291291    bitfield = tr_cpPieceBitfield( tor->completion );
  • branches/file_selection/libtransmission/torrent.c

    r2019 r2064  
    463463    }
    464464
    465     s->progress = tr_cpCompletionAsFloat( tor->completion );
    466     s->left     = tr_cpLeftBytes( tor->completion );
     465    s->progress = tr_cpCompletionAsFloat( tor->completion, CP_DONE );
     466    s->left     = tr_cpLeftBytes( tor->completion, CP_DONE );
    467467    if( tor->status & TR_STATUS_DOWNLOAD )
    468468    {
     
    930930    int            i, ret;
    931931    int            peerCount, used;
     932    int            cpState, cpPrevState;
    932933    uint8_t      * peerCompact;
    933934    tr_peer_t    * peer;
    934935
    935     tr_dbg ("torrent %s has its own thread", tor->info.name);
    936936    tr_lockLock( &tor->lock );
    937937
    938     tor->status = tr_cpIsSeeding( tor->completion ) ?
    939                       TR_STATUS_SEED : TR_STATUS_DOWNLOAD;
     938    cpState = cpPrevState = tr_cpGetState( tor->completion );
     939    switch( cpState ) {
     940        case CP_COMPLETE:   tor->status = TR_STATUS_SEED; break;
     941        case CP_DONE:       tor->status = TR_STATUS_DONE; break;
     942        case CP_INCOMPLETE: tor->status = TR_STATUS_DOWNLOAD; break;
     943    }
    940944
    941945    while( !tor->die )
     
    945949        tr_lockLock( &tor->lock );
    946950
    947         /* Are we finished ? */
    948         if( ( tor->status & TR_STATUS_DOWNLOAD ) &&
    949             tr_cpIsSeeding( tor->completion ) )
    950         {
    951             /* Done */
    952             tor->status = TR_STATUS_SEED;
    953                         tor->finished = 1;
    954             tr_trackerCompleted( tor->tracker );
     951        cpState = tr_cpGetState( tor->completion );
     952
     953        if( cpState != cpPrevState )
     954        {
     955            switch( cpState ) {
     956                case CP_COMPLETE:   tor->status = TR_STATUS_SEED; break;
     957                case CP_DONE:       tor->status = TR_STATUS_DONE; break;
     958                case CP_INCOMPLETE: tor->status = TR_STATUS_DOWNLOAD; break;
     959            }
     960
     961            tor->finished = cpState != CP_INCOMPLETE;
     962
     963            if( cpState == CP_COMPLETE )
     964                tr_trackerCompleted( tor->tracker );
     965
    955966            tr_ioSync( tor->io );
     967
     968            cpPrevState = cpState;
    956969        }
    957970
  • branches/file_selection/libtransmission/tracker.c

    r2005 r2064  
    237237    /* If there is quite a lot of people on this torrent, stress
    238238       the tracker a bit until we get a decent number of peers */
    239     if( tc->hasManyPeers && !tr_cpIsSeeding( tor->completion ) )
     239    if( tc->hasManyPeers &&
     240        (tr_cpGetState ( tor->completion ) == CP_INCOMPLETE ))
    240241    {
    241242        /* reannounce in 10 seconds if we have less than 5 peers */
     
    559560
    560561    start = ( strchr( tcInf->announce, '?' ) ? '&' : '?' );
    561     left  = tr_cpLeftBytes( tor->completion );
     562    left  = tr_cpLeftBytes( tor->completion, CP_COMPLETE );
    562563
    563564    return tr_httpClient( TR_HTTP_GET, tcInf->address, tcInf->port,
  • branches/file_selection/libtransmission/transmission.h

    r2046 r2064  
    484484struct tr_stat_s
    485485{
    486 #define TR_STATUS_CHECK_WAIT 0x001 /* Waiting in queue to check files */
    487 #define TR_STATUS_CHECK      0x002 /* Checking files */
    488 #define TR_STATUS_DOWNLOAD   0x004 /* Downloading */
    489 #define TR_STATUS_SEED       0x008 /* Seeding */
    490 #define TR_STATUS_STOPPING   0x010 /* Sending 'stopped' to the tracker */
    491 #define TR_STATUS_STOPPED    0x020 /* Sent 'stopped' but thread still
    492                                     running (for internal use only) */
    493 #define TR_STATUS_PAUSE    0x040 /* Paused */
    494 
    495 #define TR_STATUS_ACTIVE   (TR_STATUS_CHECK_WAIT|TR_STATUS_CHECK|TR_STATUS_DOWNLOAD|TR_STATUS_SEED)
     486#define TR_STATUS_CHECK_WAIT (1<<0) /* Waiting in queue to check files */
     487#define TR_STATUS_CHECK      (1<<1) /* Checking files */
     488#define TR_STATUS_DOWNLOAD   (1<<2) /* Downloading */
     489#define TR_STATUS_DONE       (1<<3) /* not at 100% so can't tell the tracker
     490                                       we're a seeder, but due to DND files
     491                                       there's nothing we want right now */
     492#define TR_STATUS_SEED       (1<<4) /* Seeding */
     493#define TR_STATUS_STOPPING   (1<<5) /* Sending 'stopped' to the tracker */
     494#define TR_STATUS_STOPPED    (1<<6) /* Sent 'stopped' but thread still
     495                                       running (for internal use only) */
     496#define TR_STATUS_PAUSE      (1<<7) /* Paused */
     497
     498#define TR_STATUS_ACTIVE   (TR_STATUS_CHECK_WAIT|TR_STATUS_CHECK|TR_STATUS_DOWNLOAD|TR_STATUS_DONE|TR_STATUS_SEED)
    496499#define TR_STATUS_INACTIVE (TR_STATUS_STOPPING|TR_STATUS_STOPPED|TR_STATUS_PAUSE)
    497500    int                 status;
  • branches/file_selection/mk/lib.mk

    r2046 r2064  
    44include ../mk/common.mk
    55
    6 SRCS = transmission.c bencode.c net.c tracker.c peer.c inout.c \
    7        metainfo.c sha1.c utils.c fdlimit.c clients.c completion.c \
    8        platform.c ratecontrol.c choking.c natpmp.c upnp.c http.c xml.c \
    9        shared.c torrent.c strlcpy.c strlcat.c ipcparse.c fastresume.c \
    10        makemeta.c
     6SRCS = bencode.c choking.c clients.c completion.c fastresume.c fdlimit.c \
     7       http.c inout.c ipcparse.c makemeta.c metainfo.c natpmp.c net.c \
     8       peer.c platform.c ratecontrol.c sha1.c shared.c strlcat.c strlcpy.c \
     9       torrent.c tracker.c transmission.c upnp.c utils.c xml.c
    1110
    1211OBJS = $(SRCS:%.c=%.o)
Note: See TracChangeset for help on using the changeset viewer.