Changeset 3105


Ignore:
Timestamp:
Sep 20, 2007, 4:32:01 PM (16 years ago)
Author:
livings124
Message:

merge encryption branch to trunk (xcode project is still out of date)

Location:
trunk
Files:
5 deleted
53 edited
14 copied

Legend:

Unmodified
Added
Removed
  • trunk/gtk/main.c

    r2554 r3105  
    168168
    169169static void
    170 safepipe(void);
    171 static void
    172170setupsighandlers(void);
    173171static void
     
    229227    gboolean     didinit, didlock, sendquit, startpaused;
    230228
    231     safepipe();                 /* ignore SIGPIPE */
    232229    argfiles = readargs( argc, argv, &sendquit, &startpaused );
    233230    didinit = cf_init( tr_getPrefsDirectory(), NULL );
     
    11081105
    11091106static void
    1110 safepipe(void) {
    1111   struct sigaction sa;
    1112 
    1113   memset(&sa, 0,  sizeof(sa));
    1114   sa.sa_handler = SIG_IGN;
    1115   sigaction(SIGPIPE, &sa, NULL);
    1116 }
    1117 
    1118 static void
    11191107setupsighandlers(void) {
    11201108  int sigs[] = {SIGHUP, SIGINT, SIGQUIT, SIGTERM};
  • trunk/gtk/torrent-inspector.c

    r2851 r3105  
    3434#include "tr_torrent.h"
    3535#include "dot-icons.h"
     36#include "lock-icon.h"
    3637#include "hig.h"
    3738#include "torrent-inspector.h"
     
    237238  PEER_COL_PROGRESS,
    238239  PEER_COL_IS_CONNECTED,
     240  PEER_COL_IS_ENCRYPTED,
    239241  PEER_COL_IS_DOWNLOADING,
    240242  PEER_COL_DOWNLOAD_RATE,
     
    251253  N_("Progress"),
    252254  " ",
     255  " ",
    253256  N_("Downloading"),
    254257  N_("DL Rate"),
     
    284287                      PEER_COL_PORT, peer->port,
    285288                      PEER_COL_CLIENT, client,
     289                      PEER_COL_IS_ENCRYPTED, peer->isEncrypted,
    286290                      PEER_COL_PROGRESS, (int)(100.0*peer->progress + 0.5),
    287291                      PEER_COL_IS_CONNECTED, peer->isConnected,
     
    315319                                         G_TYPE_INT,     /* progress [0..100] */
    316320                                         G_TYPE_BOOLEAN, /* isConnected */
     321                                         G_TYPE_BOOLEAN, /* isEncrypted */
    317322                                         G_TYPE_BOOLEAN, /* isDownloading */
    318323                                         G_TYPE_FLOAT,   /* downloadFromRate */
     
    349354
    350355static void
     356render_encrypted (GtkTreeViewColumn  * column UNUSED,
     357                  GtkCellRenderer    * renderer,
     358                  GtkTreeModel       * tree_model,
     359                  GtkTreeIter        * iter,
     360                  gpointer             data UNUSED)
     361{
     362  static GdkPixbuf * lock = NULL;
     363  gboolean is_encrypted = FALSE;
     364  gtk_tree_model_get (tree_model, iter, PEER_COL_IS_ENCRYPTED, &is_encrypted,
     365                                        -1);
     366  if (!lock) lock = gdk_pixbuf_new_from_inline (-1, lock_icon, FALSE, NULL);
     367  g_object_set (renderer, "xalign", (gfloat)0.0,
     368                          "yalign", (gfloat)0.5,
     369                          "pixbuf", (is_encrypted ? lock : NULL),
     370                          NULL);
     371}
     372
     373static void
    351374render_ul_rate (GtkTreeViewColumn  * column UNUSED,
    352375                GtkCellRenderer    * renderer,
     
    495518  /* TODO: make this configurable? */
    496519  int view_columns[] = { PEER_COL_IS_CONNECTED,
     520                         PEER_COL_IS_ENCRYPTED,
    497521                         PEER_COL_ADDRESS,
    498522                         PEER_COL_CLIENT,
     
    537561        c = gtk_tree_view_column_new_with_attributes (
    538562              _("Progress"), r, "value", PEER_COL_PROGRESS, NULL);
     563        break;
     564
     565      case PEER_COL_IS_ENCRYPTED:
     566        resizable = FALSE;
     567        r = gtk_cell_renderer_pixbuf_new ();
     568        c = gtk_tree_view_column_new_with_attributes (t, r, NULL);
     569        gtk_tree_view_column_set_sizing (c, GTK_TREE_VIEW_COLUMN_FIXED);
     570        gtk_tree_view_column_set_fixed_width (c, 32);
     571        gtk_tree_view_column_set_cell_data_func (c, r, render_encrypted,
     572                                                 NULL, NULL);
    539573        break;
    540574
  • trunk/libtransmission/Makefile.am

    r2829 r3105  
    1010    basename.c \
    1111    bencode.c \
    12     choking.c \
    1312    clients.c \
    1413    completion.c \
     14    crypto.c \
    1515    dirname.c \
    1616    fastresume.c \
    1717    fdlimit.c \
     18    handshake.c \
    1819    http.c \
    1920    inout.c \
     
    2425    natpmp.c \
    2526    net.c \
    26     peer.c \
     27    peer-io.c \
     28    peer-mgr.c \
     29    peer-msgs.c \
    2730    platform.c \
    2831    ptrarray.c \
    2932    publish.c \
    3033    ratecontrol.c \
    31     sha1.c \
    3234    shared.c \
    3335    strlcat.c \
    3436    strlcpy.c \
    35     timer.c \
    3637    torrent.c \
    3738    tracker.c \
     
    4647    bsdqueue.h \
    4748    bsdtree.h \
    48     choking.h \
    4949    clients.h \
     50    crypto.h \
    5051    completion.h \
    5152    fastresume.h \
    5253    fdlimit.h \
     54    handshake.h \
    5355    http.h \
    5456    inout.h \
     
    6062    natpmp.h \
    6163    net.h \
    62     peeraz.h \
    63     peerext.h \
    64     peer.h \
    65     peermessages.h \
    66     peerparse.h \
    67     peertree.h \
    68     peerutils.h \
     64    peer-io.h \
     65    peer-mgr.h \
     66    peer-mgr-private.h \
     67    peer-msgs.h \
    6968    platform.h \
    7069    ptrarray.h \
    7170    publish.h \
    7271    ratecontrol.h \
    73     sha1.h \
    7472    shared.h \
    75     timer.h \
    7673    tracker.h \
    7774    transmission.h \
  • trunk/libtransmission/bencode.c

    r2555 r3105  
    365365    benc_val_t * item;
    366366
    367     assert( TYPE_LIST == list->type );
     367    assert( tr_bencIsList( list ) );
    368368    assert( list->val.l.count < list->val.l.alloc );
    369369
     
    379379    benc_val_t * keyval, * itemval;
    380380
    381     assert( TYPE_DICT == dict->type );
     381    assert( tr_bencIsDict( dict ) );
    382382    assert( dict->val.l.count + 2 <= dict->val.l.alloc );
    383383
     
    480480    return 0;
    481481}
     482
     483/**
     484***
     485**/
     486
     487int
     488tr_bencIsStr ( const benc_val_t * val )
     489{
     490    return val!=NULL && val->type==TYPE_STR;
     491}
     492
     493int
     494tr_bencIsInt ( const benc_val_t * val )
     495{
     496    return val!=NULL && val->type==TYPE_INT;
     497}
     498
     499int
     500tr_bencIsList( const benc_val_t * val )
     501{
     502    return val!=NULL && val->type==TYPE_LIST;
     503}
     504
     505int
     506tr_bencIsDict( const benc_val_t * val )
     507{
     508    return val!=NULL && val->type==TYPE_DICT;
     509}
  • trunk/libtransmission/bencode.h

    r2076 r3105  
    9191                          int * used, int * max );
    9292
     93int    tr_bencIsStr   ( const benc_val_t * val );
     94int    tr_bencIsInt   ( const benc_val_t * val );
     95int    tr_bencIsList  ( const benc_val_t * val );
     96int    tr_bencIsDict  ( const benc_val_t * val );
     97
    9398#endif
  • trunk/libtransmission/clients.c

    r2713 r3105  
    4545}
    4646
    47 char * tr_clientForId( uint8_t * id )
     47char * tr_clientForId( const uint8_t * id )
    4848{
    4949    char * ret = NULL;
  • trunk/libtransmission/clients.h

    r261 r3105  
    2323 *****************************************************************************/
    2424
    25 char * tr_clientForId( uint8_t * );
     25char * tr_clientForId( const uint8_t * );
  • trunk/libtransmission/completion.c

    r2897 r3105  
    3030#include "utils.h"
    3131
    32 struct tr_completion_s
    33 {
    34     tr_torrent_t * tor;
    35 
    36     /* true if a peer is requesting this block */
    37     tr_bitfield_t * blockRequested;
     32struct tr_completion
     33{
     34    tr_torrent * tor;
    3835
    3936    /* do we have this block? */
    40     tr_bitfield_t * blockBitfield;
     37    tr_bitfield * blockBitfield;
    4138
    4239    /* do we have this piece? */
    43     tr_bitfield_t * pieceBitfield;
     40    tr_bitfield * pieceBitfield;
    4441
    4542    /* a block is complete if and only if we have it */
     
    5249};
    5350
    54 tr_completion_t * tr_cpInit( tr_torrent_t * tor )
    55 {
    56     tr_completion_t * cp;
    57 
    58     cp                   = tr_new( tr_completion_t, 1 );
     51tr_completion * tr_cpInit( tr_torrent * tor )
     52{
     53    tr_completion * cp;
     54
     55    cp                   = tr_new( tr_completion, 1 );
    5956    cp->tor              = tor;
    6057    cp->blockBitfield    = tr_bitfieldNew( tor->blockCount );
    61     cp->blockRequested   = tr_bitfieldNew( tor->blockCount );
    6258    cp->pieceBitfield    = tr_bitfieldNew( tor->info.pieceCount );
    6359    cp->completeBlocks   = tr_new( uint16_t, tor->info.pieceCount );
     
    6864}
    6965
    70 void tr_cpClose( tr_completion_t * cp )
     66void tr_cpClose( tr_completion * cp )
    7167{
    7268    tr_free(         cp->completeBlocks );
    7369    tr_bitfieldFree( cp->pieceBitfield );
    74     tr_bitfieldFree( cp->blockRequested );
    7570    tr_bitfieldFree( cp->blockBitfield );
    7671    tr_free(         cp );
    7772}
    7873
    79 void tr_cpReset( tr_completion_t * cp )
    80 {
    81     tr_torrent_t * tor = cp->tor;
     74void tr_cpReset( tr_completion * cp )
     75{
     76    tr_torrent * tor = cp->tor;
    8277
    8378    tr_bitfieldClear( cp->pieceBitfield );
    8479    tr_bitfieldClear( cp->blockBitfield );
    85     tr_bitfieldClear( cp->blockRequested );
    8680    memset( cp->completeBlocks, 0, sizeof(uint16_t) * tor->info.pieceCount );
    8781
     
    9791
    9892static void
    99 tr_cpEnsureDoneValid( const tr_completion_t * ccp )
    100 {
    101     const tr_torrent_t * tor = ccp->tor;
     93tr_cpEnsureDoneValid( const tr_completion * ccp )
     94{
     95    const tr_torrent * tor = ccp->tor;
    10296    const tr_info_t * info = &tor->info;
    10397    uint64_t have=0, total=0;
    10498    int i;
    105     tr_completion_t * cp ;
     99    tr_completion * cp ;
    106100
    107101    if( !ccp->doneDirty )
     
    109103
    110104    /* too bad C doesn't have 'mutable' */
    111     cp = (tr_completion_t*) ccp;
     105    cp = (tr_completion*) ccp;
    112106    cp->doneDirty = FALSE;
    113107
     
    136130
    137131void
    138 tr_cpInvalidateDND ( tr_completion_t * cp )
     132tr_cpInvalidateDND ( tr_completion * cp )
    139133{
    140134    cp->doneDirty = TRUE;
    141135}
    142136
    143 int tr_cpPieceIsComplete( const tr_completion_t * cp, int piece )
     137int
     138tr_cpPieceIsComplete( const tr_completion * cp, int piece )
    144139{
    145140    return cp->completeBlocks[piece] >= tr_torPieceCountBlocks(cp->tor,piece);
    146141}
    147142
    148 const tr_bitfield_t * tr_cpPieceBitfield( const tr_completion_t * cp )
     143const tr_bitfield * tr_cpPieceBitfield( const tr_completion * cp )
    149144{
    150145    return cp->pieceBitfield;
    151146}
    152147
    153 void tr_cpPieceAdd( tr_completion_t * cp, int piece )
    154 {
    155     const tr_torrent_t * tor = cp->tor;
     148void tr_cpPieceAdd( tr_completion * cp, int piece )
     149{
     150    const tr_torrent * tor = cp->tor;
    156151    const int start = tr_torPieceFirstBlock(tor,piece);
    157152    const int end = start + tr_torPieceCountBlocks(tor,piece);
     
    162157}
    163158
    164 void tr_cpPieceRem( tr_completion_t * cp, int piece )
    165 {
    166     const tr_torrent_t * tor = cp->tor;
     159void tr_cpPieceRem( tr_completion * cp, int piece )
     160{
     161    const tr_torrent * tor = cp->tor;
    167162    const int start = tr_torPieceFirstBlock(tor,piece);
    168163    const int end = start + tr_torPieceCountBlocks(tor,piece);
     
    191186}
    192187
    193 /* Blocks */
    194 void tr_cpDownloaderAdd( tr_completion_t * cp, int block )
    195 {
    196     tr_bitfieldAdd( cp->blockRequested, block );
    197 }
    198 
    199 void tr_cpDownloaderRem( tr_completion_t * cp, int block )
    200 {
    201     tr_bitfieldRem( cp->blockRequested, block );
    202 }
    203 
    204 int tr_cpBlockIsComplete( const tr_completion_t * cp, int block )
    205 {
    206     return tr_bitfieldHas( cp->blockBitfield, block );
     188int tr_cpBlockIsComplete( const tr_completion * cp, int block )
     189{
     190    return tr_bitfieldHas( cp->blockBitfield, block ) ? 1 : 0;
    207191}
    208192
    209193void
    210 tr_cpBlockAdd( tr_completion_t * cp, int block )
    211 {
    212     const tr_torrent_t * tor = cp->tor;
     194tr_cpBlockAdd( tr_completion * cp, int block )
     195{
     196    const tr_torrent * tor = cp->tor;
    213197
    214198    if( !tr_cpBlockIsComplete( cp, block ) )
     
    231215}
    232216
    233 const tr_bitfield_t * tr_cpBlockBitfield( const tr_completion_t * cp )
     217const tr_bitfield * tr_cpBlockBitfield( const tr_completion * cp )
    234218{
    235219    assert( cp != NULL );
     
    239223
    240224void
    241 tr_cpBlockBitfieldSet( tr_completion_t * cp, tr_bitfield_t * bitfield )
     225tr_cpBlockBitfieldSet( tr_completion * cp, tr_bitfield * bitfield )
    242226{
    243227    int i;
     
    253237}
    254238
    255 float tr_cpPercentBlocksInPiece( const tr_completion_t * cp, int piece )
     239float tr_cpPercentBlocksInPiece( const tr_completion * cp, int piece )
    256240{
    257241    assert( cp != NULL );
    258242
    259243    return (double)cp->completeBlocks[piece] / tr_torPieceCountBlocks(cp->tor,piece);
    260 }
    261 
    262 int
    263 tr_cpMissingBlocksForPiece( const tr_completion_t * cp, int piece )
    264 {
    265     int i;
    266     int n;
    267     const tr_torrent_t * tor = cp->tor;
    268     const int start = tr_torPieceFirstBlock(tor,piece);
    269     const int end   = start + tr_torPieceCountBlocks(tor,piece);
    270 
    271     n = 0;
    272     for( i = start; i < end; ++i )
    273         if( !tr_cpBlockIsComplete( cp, i ) && !tr_bitfieldHas( cp->blockRequested, i ) )
    274             ++n;
    275 
    276     return n;
    277 }
    278 
    279 int tr_cpMissingBlockInPiece( const tr_completion_t * cp, int piece )
    280 {
    281     int i;
    282     const tr_torrent_t * tor = cp->tor;
    283     const int start = tr_torPieceFirstBlock(tor,piece);
    284     const int end   = start + tr_torPieceCountBlocks(tor,piece);
    285 
    286     for( i = start; i < end; ++i )
    287         if( !tr_cpBlockIsComplete( cp, i ) && !tr_bitfieldHas( cp->blockRequested, i ) )
    288             return i;
    289 
    290     return -1;
    291244}
    292245
     
    296249
    297250float
    298 tr_cpPercentComplete ( const tr_completion_t * cp )
     251tr_cpPercentComplete ( const tr_completion * cp )
    299252{
    300253    return (double)cp->completeHave / cp->tor->info.totalSize;
     
    302255
    303256uint64_t
    304 tr_cpLeftUntilComplete ( const tr_completion_t * cp )
     257tr_cpLeftUntilComplete ( const tr_completion * cp )
    305258{
    306259    return cp->tor->info.totalSize - cp->completeHave;
     
    308261
    309262float
    310 tr_cpPercentDone( const tr_completion_t * cp )
     263tr_cpPercentDone( const tr_completion * cp )
    311264{
    312265    tr_cpEnsureDoneValid( cp );
     
    316269
    317270uint64_t
    318 tr_cpLeftUntilDone ( const tr_completion_t * cp )
     271tr_cpLeftUntilDone ( const tr_completion * cp )
    319272{
    320273    tr_cpEnsureDoneValid( cp );
     
    324277
    325278cp_status_t
    326 tr_cpGetStatus ( const tr_completion_t * cp )
     279tr_cpGetStatus ( const tr_completion * cp )
    327280{
    328281    if( cp->completeHave >= cp->tor->info.totalSize )
     
    338291
    339292uint64_t
    340 tr_cpDownloadedValid( const tr_completion_t * cp )
     293tr_cpDownloadedValid( const tr_completion * cp )
    341294{
    342295    uint64_t b = 0;
    343     const tr_torrent_t * tor = cp->tor;
     296    const tr_torrent * tor = cp->tor;
    344297    const tr_info_t * info = &tor->info;
    345298    int i;
  • trunk/libtransmission/completion.h

    r2891 r3105  
    2828#include "transmission.h"
    2929
    30 typedef struct tr_completion_s tr_completion_t;
     30typedef struct tr_completion tr_completion;
    3131
    32 tr_completion_t     * tr_cpInit( tr_torrent_t * );
    33 void                  tr_cpClose( tr_completion_t * );
    34 void                  tr_cpReset( tr_completion_t * );
     32tr_completion  * tr_cpInit( tr_torrent * );
     33void             tr_cpClose( tr_completion * );
     34void             tr_cpReset( tr_completion * );
    3535
    3636/* General */
    3737
    38 cp_status_t           tr_cpGetStatus ( const tr_completion_t * );
    39 uint64_t              tr_cpDownloadedValid( const tr_completion_t * );
    40 uint64_t              tr_cpLeftUntilComplete( const tr_completion_t * );
    41 uint64_t              tr_cpLeftUntilDone( const tr_completion_t * );
    42 float                 tr_cpPercentComplete( const tr_completion_t * );
    43 float                 tr_cpPercentDone( const tr_completion_t * );
    44 void                  tr_cpInvalidateDND ( tr_completion_t * );
     38cp_status_t      tr_cpGetStatus ( const tr_completion * );
     39uint64_t         tr_cpDownloadedValid( const tr_completion * );
     40uint64_t         tr_cpLeftUntilComplete( const tr_completion * );
     41uint64_t         tr_cpLeftUntilDone( const tr_completion * );
     42float            tr_cpPercentComplete( const tr_completion * );
     43float            tr_cpPercentDone( const tr_completion * );
     44void             tr_cpInvalidateDND ( tr_completion * );
    4545
    4646/* Pieces */
    47 int                   tr_cpPieceIsComplete( const tr_completion_t *, int piece );
    48 void                  tr_cpPieceAdd( tr_completion_t *, int piece );
    49 void                  tr_cpPieceRem( tr_completion_t *, int piece );
     47int              tr_cpPieceIsComplete( const tr_completion *, int piece );
     48void             tr_cpPieceAdd( tr_completion *, int piece );
     49void             tr_cpPieceRem( tr_completion *, int piece );
    5050
    5151/* Blocks */
    52 void                  tr_cpDownloaderAdd( tr_completion_t *, int block );
    53 void                  tr_cpDownloaderRem( tr_completion_t *, int block );
    54 int                   tr_cpBlockIsComplete( const tr_completion_t *, int block );
    55 void                  tr_cpBlockAdd( tr_completion_t *, int block );
    56 void                  tr_cpBlockBitfieldSet( tr_completion_t *, struct tr_bitfield_s * );
    57 float                 tr_cpPercentBlocksInPiece( const tr_completion_t * cp, int piece );
    58 /* Missing = we don't have it and we are not getting it from any peer yet */
    59 int                   tr_cpMissingBlocksForPiece( const tr_completion_t * cp, int piece );
    60 int                   tr_cpMissingBlockInPiece( const tr_completion_t *, int piece );
     52int              tr_cpBlockIsComplete( const tr_completion *, int block );
     53void             tr_cpBlockAdd( tr_completion *, int block );
     54void             tr_cpBlockBitfieldSet( tr_completion *, struct tr_bitfield * );
     55float            tr_cpPercentBlocksInPiece( const tr_completion * cp, int piece );
    6156
    62 const struct tr_bitfield_s * tr_cpPieceBitfield( const tr_completion_t* );
    63 const struct tr_bitfield_s * tr_cpBlockBitfield( const tr_completion_t * );
     57const struct tr_bitfield * tr_cpPieceBitfield( const tr_completion* );
     58const struct tr_bitfield * tr_cpBlockBitfield( const tr_completion * );
    6459
    6560#endif
  • trunk/libtransmission/fastresume.c

    r2891 r3105  
    5656#include "completion.h"
    5757#include "fastresume.h"
    58 #include "peer.h"
     58#include "peer-mgr.h"
    5959#include "platform.h"
    6060#include "utils.h"
     
    7575
    7676    /* IPs and ports of connectable peers */
    77     FR_ID_PEERS = 4,
     77    FR_ID_PEERS_OLD = 4,
    7878
    7979    /* progress data:
     
    8989    /* transfer speeds
    9090     * uint32_t: dl speed rate to use when the mode is single
    91      * uint32_t: dl's tr_speedlimit_t
     91     * uint32_t: dl's tr_speedlimit
    9292     * uint32_t: ul speed rate to use when the mode is single
    93      * uint32_t: ul's tr_speedlimit_t
     93     * uint32_t: ul's tr_speedlimit
    9494     */
    9595    FR_ID_SPEED = 8,
     
    101101
    102102    /* number of corrupt bytes downloaded */
    103     FR_ID_CORRUPT = 10
     103    FR_ID_CORRUPT = 10,
     104
     105    /* IPs and ports of connectable peers */
     106    FR_ID_PEERS = 11
    104107};
    105108
     
    115118
    116119static void
    117 fastResumeFileName( char * buf, size_t buflen, const tr_torrent_t * tor, int tag )
     120fastResumeFileName( char * buf, size_t buflen, const tr_torrent * tor, int tag )
    118121{
    119122    const char * cacheDir = tr_getCacheDirectory ();
     
    133136
    134137static tr_time_t*
    135 getMTimes( const tr_torrent_t * tor, int * setme_n )
     138getMTimes( const tr_torrent * tor, int * setme_n )
    136139{
    137140    int i;
     
    172175
    173176void
    174 tr_fastResumeSave( const tr_torrent_t * tor )
     177tr_fastResumeSave( const tr_torrent * tor )
    175178{
    176179    char      path[MAX_PATH_LENGTH];
     
    195198        uint8_t * buf = malloc( FR_PROGRESS_LEN( tor ) );
    196199        uint8_t * walk = buf;
    197         const tr_bitfield_t * bitfield;
     200        const tr_bitfield * bitfield;
    198201
    199202        /* mtimes */
     
    284287
    285288    /* Write download and upload totals */
     289
    286290    total = tor->downloadedCur + tor->downloadedPrev;
    287291    fastResumeWriteData( FR_ID_DOWNLOADED, &total, 8, 1, file );
     292
    288293    total = tor->uploadedCur + tor->uploadedPrev;
    289294    fastResumeWriteData( FR_ID_UPLOADED, &total, 8, 1, file );
     295
    290296    total = tor->corruptCur + tor->corruptPrev;
    291297    fastResumeWriteData( FR_ID_CORRUPT, &total, 8, 1, file );
     
    293299    if( !( TR_FLAG_PRIVATE & tor->info.flags ) )
    294300    {
    295         /* Write IPs and ports of connectable peers, if any */
    296         int size;
    297         uint8_t * buf = NULL;
    298         if( ( size = tr_peerGetConnectable( tor, &buf ) ) > 0 )
    299         {
    300             fastResumeWriteData( FR_ID_PEERS, buf, size, 1, file );
    301             free( buf );
    302         }
     301        tr_pex * pex;
     302        const int count = tr_peerMgrGetPeers( tor->handle->peerMgr,
     303                                              tor->info.hash,
     304                                              &pex );
     305        if( count > 0 )
     306            fastResumeWriteData( FR_ID_PEERS, pex, sizeof(tr_pex), count, file );
     307        tr_free( pex );
    303308    }
    304309
     
    309314
    310315static int
    311 loadSpeeds( tr_torrent_t * tor, FILE * file )
     316loadSpeeds( tr_torrent * tor, FILE * file )
    312317{
    313318    const size_t len = FR_SPEED_LEN;
     
    326331    tr_torrentSetSpeedLimit( tor, TR_DOWN, i16 );
    327332    memcpy( &i8, walk, 1 ); walk += 1;
    328     tr_torrentSetSpeedMode( tor, TR_DOWN, (tr_speedlimit_t)i8 );
     333    tr_torrentSetSpeedMode( tor, TR_DOWN, (tr_speedlimit)i8 );
    329334    memcpy( &i16, walk, 2 ); walk += 2;
    330335    tr_torrentSetSpeedLimit( tor, TR_UP, i16 );
    331336    memcpy( &i8, walk, 1 ); walk += 1;
    332     tr_torrentSetSpeedMode( tor, TR_UP, (tr_speedlimit_t)i8 );
     337    tr_torrentSetSpeedMode( tor, TR_UP, (tr_speedlimit)i8 );
    333338
    334339    tr_free( buf );
     
    338343
    339344static int
    340 loadPriorities( tr_torrent_t * tor,
    341                 FILE         * file )
     345loadPriorities( tr_torrent * tor,
     346                FILE       * file )
    342347{
    343348    const size_t n = tor->info.fileCount;
     
    388393
    389394static int
    390 fastResumeLoadProgress( const tr_torrent_t  * tor,
    391                         tr_bitfield_t       * uncheckedPieces,
    392                         FILE                * file )
     395fastResumeLoadProgress( const tr_torrent  * tor,
     396                        tr_bitfield       * uncheckedPieces,
     397                        FILE              * file )
    393398{
    394399    int i;
     
    410415        for( i=0; i<n; ++i ) {
    411416            if ( curMTimes[i]!=oldMTimes[i] ) {
    412                 const tr_file_t * file = &tor->info.files[i];
     417                const tr_file * file = &tor->info.files[i];
    413418                tr_dbg( "File '%s' mtimes differ-- flagging pieces [%d..%d] for recheck",
    414419                        file->name, file->firstPiece, file->lastPiece);
     
    423428    /* get the completion bitfield */
    424429    if (1) {
    425         tr_bitfield_t bitfield;
     430        tr_bitfield bitfield;
    426431        memset( &bitfield, 0, sizeof bitfield );
    427432        bitfield.len = FR_BLOCK_BITFIELD_LEN( tor );
     
    442447
    443448static uint64_t
    444 fastResumeLoadOld( tr_torrent_t   * tor,
    445                    tr_bitfield_t  * uncheckedPieces,
    446                    FILE           * file )
     449fastResumeLoadOld( tr_torrent   * tor,
     450                   tr_bitfield  * uncheckedPieces,
     451                   FILE         * file )
    447452{
    448453    uint64_t ret = 0;
     
    476481
    477482static uint64_t
    478 fastResumeLoadImpl ( tr_torrent_t   * tor,
    479                      tr_bitfield_t  * uncheckedPieces )
     483fastResumeLoadImpl ( tr_torrent   * tor,
     484                     tr_bitfield  * uncheckedPieces )
    480485{
    481486    char      path[MAX_PATH_LENGTH];
     
    637642                break;
    638643
     644            case FR_ID_PEERS_OLD:
     645                if( !( TR_FLAG_PRIVATE & tor->info.flags ) )
     646                {
     647                    uint8_t * buf = malloc( len );
     648                    if( 1 != fread( buf, len, 1, file ) )
     649                    {
     650                        free( buf );
     651                        fclose( file );
     652                        return ret;
     653                    }
     654
     655                    tr_peerMgrAddPeers( tor->handle->peerMgr,
     656                                        tor->info.hash,
     657                                        TR_PEER_FROM_CACHE,
     658                                        buf, len / 6 );
     659
     660                    tr_dbg( "found %i peers in resume file", len/6 );
     661                    free( buf );
     662                    ret |= TR_FR_PEERS;
     663                }
     664
    639665            case FR_ID_PEERS:
    640666                if( !( TR_FLAG_PRIVATE & tor->info.flags ) )
    641667                {
    642                     int used;
    643                     uint8_t * buf = malloc( len );
    644                     if( 1 != fread( buf, len, 1, file ) )
    645                     {
    646                         free( buf );
    647                         fclose( file );
    648                         return ret;
    649                     }
    650                     used = tr_torrentAddCompact( tor, TR_PEER_FROM_CACHE,
    651                                                  buf, len / 6 );
    652                     tr_dbg( "found %i peers in resume file, used %i",
    653                             len / 6, used );
    654                     free( buf );
     668                    const int count = len / sizeof(tr_pex);
     669                    tr_pex * pex = tr_new0( tr_pex, count );
     670                    if( 1 != fread( pex, sizeof(tr_pex), count, file ) )
     671                    {
     672                        free( pex );
     673                        fclose( file );
     674                        return ret;
     675                    }
     676
     677                    tr_peerMgrAddPex( tor->handle->peerMgr,
     678                                      tor->info.hash,
     679                                      TR_PEER_FROM_CACHE,
     680                                      pex, count );
     681
     682                    tr_dbg( "found %i peers in resume file", len/6 );
     683                    free( pex );
    655684                    ret |= TR_FR_PEERS;
    656685                }
     
    671700
    672701uint64_t
    673 tr_fastResumeLoad( tr_torrent_t   * tor,
    674                    tr_bitfield_t  * uncheckedPieces )
     702tr_fastResumeLoad( tr_torrent   * tor,
     703                   tr_bitfield  * uncheckedPieces )
    675704{
    676705    const uint64_t ret = fastResumeLoadImpl( tor, uncheckedPieces );
  • trunk/libtransmission/fastresume.h

    r2891 r3105  
    2626#define TR_FAST_RESUME_H
    2727
    28 void tr_fastResumeSave( const tr_torrent_t * tor );
     28void tr_fastResumeSave( const tr_torrent * tor );
    2929
    3030enum
     
    4343 * Returns a bitwise-or'ed set of the data loaded from fastresume
    4444 */
    45 uint64_t tr_fastResumeLoad( tr_torrent_t         * tor,
    46                             struct tr_bitfield_s * uncheckedPieces );
     45uint64_t tr_fastResumeLoad( tr_torrent         * tor,
     46                            struct tr_bitfield * uncheckedPieces );
    4747
    4848#endif
  • trunk/libtransmission/fdlimit.c

    r2596 r3105  
    6464typedef struct tr_fd_s
    6565{
    66     tr_lock_t     * lock;
    67     tr_cond_t     * cond;
     66    tr_lock       * lock;
     67    tr_cond       * cond;
    6868   
    6969    int             reserved;
     
    391391void tr_fdSocketClose( int s )
    392392{
    393     tr_lockLock( gFd->lock );
     393    if( s >= 0 )
     394    {
     395        tr_lockLock( gFd->lock );
    394396#ifdef BEOS_NETSERVER
    395     closesocket( s );
     397        closesocket( s );
    396398#else
    397     close( s );
     399        close( s );
    398400#endif
    399     if( SocketGetPriority( s ) )
    400         gFd->reserved--;
    401     else
    402         gFd->normal--;
    403     tr_lockUnlock( gFd->lock );
     401        if( SocketGetPriority( s ) )
     402            gFd->reserved--;
     403        else
     404            gFd->normal--;
     405        tr_lockUnlock( gFd->lock );
     406    }
    404407}
    405408
  • trunk/libtransmission/http.c

    r2686 r3105  
    3232#include <sys/types.h>
    3333
     34#include "evdns.h"
     35
    3436#ifdef __BEOS__
    3537extern int vasprintf( char **, const char *, va_list );
     
    8587#define HTTP_LENGTH_CHUNKED     4
    8688    char           lengthtype;
    87     tr_resolve_t * resolve;
    8889    char         * host;
    8990    int            port;
     
    568569}
    569570
     571static void
     572resolve_cb( int result, char type, int count, int ttl, void *addresses, void *arg)
     573{
     574    tr_http_t * http = (tr_http_t *) arg;
     575
     576    if( (result!=DNS_ERR_NONE) || (type!=DNS_IPv4_A) || (ttl<0) || (count<1) )
     577        http->state = HTTP_STATE_ERROR;
     578    else {
     579         struct in_addr *in_addrs = addresses;
     580         http->sock = tr_netOpenTCP( &in_addrs[0], htons(http->port), 1 );
     581         http->state = HTTP_STATE_CONNECT;
     582    }
     583}
     584
    570585tr_tristate_t
    571586tr_httpPulse( tr_http_t * http, const char ** data, int * len )
     
    587602                break;
    588603            }
    589             http->resolve = tr_netResolveInit( http->host );
    590             if( NULL == http->resolve )
     604            if( evdns_resolve_ipv4( http->host, 0, resolve_cb, http ) )
    591605            {
    592606                goto err;
     
    596610
    597611        case HTTP_STATE_RESOLVE:
    598             switch( tr_netResolvePulse( http->resolve, &addr ) )
    599             {
    600                 case TR_NET_WAIT:
    601                     return TR_NET_WAIT;
    602                 case TR_NET_ERROR:
    603                     goto err;
    604                 case TR_NET_OK:
    605                     tr_netResolveClose( http->resolve );
    606                     http->resolve = NULL;
    607                     http->sock = tr_netOpenTCP( &addr, htons( http->port ), 1 );
    608                     http->state = HTTP_STATE_CONNECT;
    609             }
    610             /* fallthrough */
     612            return TR_NET_WAIT;
    611613
    612614        case HTTP_STATE_CONNECT:
     
    898900tr_httpClose( tr_http_t * http )
    899901{
    900     if( NULL != http->resolve )
    901     {
    902         tr_netResolveClose( http->resolve );
    903     }
    904902    free( http->host );
    905     if( 0 <= http->sock )
    906     {
    907         tr_netClose( http->sock );
    908     }
     903    tr_netClose( http->sock );
    909904    free( http->header.buf );
    910905    free( http->body.buf );
  • trunk/libtransmission/inout.c

    r2994 r3105  
    2121#include "transmission.h"
    2222#include "completion.h"
     23#include "crypto.h"
     24#include "fastresume.h"
    2325#include "fdlimit.h"
    2426#include "inout.h"
     27#include "list.h"
    2528#include "net.h"
    26 #include "peer.h"
    27 #include "sha1.h"
     29#include "platform.h"
     30#include "peer-mgr.h"
    2831#include "utils.h"
    2932
    30 struct tr_io_s
    31 {
    32     tr_torrent_t * tor;
     33struct tr_io
     34{
     35    tr_torrent * tor;
    3336};
    3437
     
    3740****/
    3841
    39 enum { TR_IO_READ, TR_IO_WRITE };
    40 
    4142#ifdef WIN32
    4243#define lseek _lseeki64
    4344#endif
    4445
    45 static int
    46 readOrWriteBytes ( const tr_torrent_t  * tor,
     46enum { TR_IO_READ, TR_IO_WRITE };
     47
     48static int
     49readOrWriteBytes ( const tr_torrent    * tor,
    4750                   int                   ioMode,
    4851                   int                   fileIndex,
     
    5154                   size_t                buflen )
    5255{
    53     const tr_info_t * info = &tor->info;
    54     const tr_file_t * file = &info->files[fileIndex];
     56    const tr_info * info = &tor->info;
     57    const tr_file * file = &info->files[fileIndex];
    5558    typedef size_t (* iofunc) ( int, void *, size_t );
    5659    iofunc func = ioMode == TR_IO_READ ? (iofunc)read : (iofunc)write;
     
    8689
    8790static void
    88 findFileLocation ( const tr_torrent_t * tor,
     91findFileLocation ( const tr_torrent * tor,
    8992                   int                  pieceIndex,
    9093                   int                  pieceOffset,
     
    9295                   uint64_t           * fileOffset )
    9396{
    94     const tr_info_t * info = &tor->info;
     97    const tr_info * info = &tor->info;
    9598
    9699    int i;
     
    113116
    114117static int
    115 ensureMinimumFileSize ( const tr_torrent_t  * tor,
     118ensureMinimumFileSize ( const tr_torrent  * tor,
    116119                        int                   fileIndex,
    117120                        uint64_t              minSize ) /* in bytes */
     
    120123    int ret;
    121124    struct stat sb;
    122     const tr_file_t * file = &tor->info.files[fileIndex];
     125    const tr_file * file = &tor->info.files[fileIndex];
    123126
    124127    assert ( 0<=fileIndex && fileIndex<tor->info.fileCount );
     
    144147
    145148static int
    146 readOrWritePiece ( tr_torrent_t       * tor,
    147                    int                  ioMode,
    148                    int                  pieceIndex,
    149                    int                  pieceOffset,
    150                    uint8_t            * buf,
    151                    size_t               buflen )
     149readOrWritePiece ( tr_torrent       * tor,
     150                   int                ioMode,
     151                   int                pieceIndex,
     152                   int                pieceOffset,
     153                   uint8_t          * buf,
     154                   size_t             buflen )
    152155{
    153156    int ret = 0;
    154157    int fileIndex;
    155158    uint64_t fileOffset;
    156     const tr_info_t * info = &tor->info;
     159    const tr_info * info = &tor->info;
    157160
    158161    assert( 0<=pieceIndex && pieceIndex<tor->info.pieceCount );
     
    163166    while( buflen && !ret )
    164167    {
    165         const tr_file_t * file = &info->files[fileIndex];
     168        const tr_file * file = &info->files[fileIndex];
    166169        const uint64_t bytesThisPass = MIN( buflen, file->length - fileOffset );
    167170
     
    182185
    183186int
    184 tr_ioRead( tr_io_t * io, int pieceIndex, int begin, int len, uint8_t * buf )
    185 {
    186     return readOrWritePiece ( io->tor, TR_IO_READ, pieceIndex, begin, buf, len );
     187tr_ioRead( tr_torrent * tor, int pieceIndex, int begin, int len, uint8_t * buf )
     188{
     189    return readOrWritePiece ( tor, TR_IO_READ, pieceIndex, begin, buf, len );
    187190}
    188191
    189192int
    190 tr_ioWrite( tr_io_t * io, int pieceIndex, int begin, int len, uint8_t * buf )
    191 {
    192     return readOrWritePiece ( io->tor, TR_IO_WRITE, pieceIndex, begin, buf, len );
     193tr_ioWrite( tr_torrent * tor, int pieceIndex, int begin, int len, uint8_t * buf )
     194{
     195    return readOrWritePiece ( tor, TR_IO_WRITE, pieceIndex, begin, buf, len );
    193196}
    194197
     
    198201
    199202static int
    200 tr_ioRecalculateHash ( tr_torrent_t  * tor,
     203tr_ioRecalculateHash ( tr_torrent    * tor,
    201204                       int             pieceIndex,
    202205                       uint8_t       * setme )
     
    205208    int ret;
    206209    uint8_t * buf;
    207     const tr_info_t * info;
     210    const tr_info * info;
    208211
    209212    assert( tor != NULL );
     
    216219    buf = malloc( n );
    217220    ret = readOrWritePiece ( tor, TR_IO_READ, pieceIndex, 0, buf, n );
    218     if( !ret ) {
    219         SHA1( buf, n, setme );
    220     }
     221    if( !ret )
     222        tr_sha1( setme, buf, n, NULL );
    221223    free( buf );
    222224
     
    225227
    226228static int
    227 checkPiece ( tr_torrent_t * tor, int pieceIndex )
     229checkPiece ( tr_torrent * tor, int pieceIndex )
    228230{
    229231    uint8_t hash[SHA_DIGEST_LENGTH];
     
    235237}
    236238
     239/**
     240***
     241**/
     242
    237243void
    238 tr_ioCheckFiles( tr_torrent_t * tor )
    239 {
    240     assert( tor != NULL );
    241     assert( tor->completion != NULL );
    242     assert( tor->info.pieceCount > 0 );
    243 
    244     if( tor->uncheckedPieces != NULL )
     244tr_ioClose( const tr_torrent * tor )
     245{
     246    int i;
     247    const tr_info * info = &tor->info;
     248
     249    for( i=0; i<info->fileCount; ++i )
     250        tr_fdFileClose( tor->destination, info->files[i].name );
     251}
     252
     253int
     254tr_ioHash( tr_torrent * tor, int pieceIndex )
     255{
     256    int ret;
     257    const int success = !checkPiece( tor, pieceIndex );
     258
     259    if( success )
     260    {
     261        tr_dbg( "Piece %d hash OK", pieceIndex );
     262        tr_cpPieceAdd( tor->completion, pieceIndex );
     263        ret = TR_OK;
     264    }
     265    else
     266    {
     267        tr_err( "Piece %d hash FAILED", pieceIndex );
     268        tr_cpPieceRem( tor->completion, pieceIndex );
     269        ret = TR_ERROR;
     270    }
     271
     272    tr_peerMgrSetBlame( tor->handle->peerMgr, tor->info.hash, pieceIndex, success );
     273
     274    return ret;
     275}
     276
     277/**
     278***
     279**/
     280
     281struct recheck_node
     282{
     283    tr_torrent * torrent;
     284    tr_recheck_done_cb recheck_done_cb;
     285    run_status_t status_when_done;
     286};
     287
     288static void
     289fireCheckDone( tr_torrent          * torrent,
     290               tr_recheck_done_cb    recheck_done_cb,
     291               run_status_t          status_when_done )
     292{
     293    torrent->runStatus = status_when_done;
     294    (*recheck_done_cb)( torrent );
     295}
     296
     297struct recheck_node currentNode;
     298
     299static tr_list * recheckList = NULL;
     300
     301static tr_thread * recheckThread = NULL;
     302
     303static int stopCurrent = FALSE;
     304
     305static void
     306recheckThreadFunc( void * unused UNUSED )
     307{
     308    for( ;; )
    245309    {
    246310        int i;
     311        tr_torrent * tor;
     312
     313        struct recheck_node * node = (struct recheck_node*) recheckList ? recheckList->data : NULL;
     314        if( node == NULL )
     315            break;
     316
     317        currentNode = *node;
     318        tor = currentNode.torrent;
     319        tr_list_remove_data( &recheckList, node );
     320        tr_free( node );
     321
     322        if( tor->uncheckedPieces == NULL ) {
     323            fireCheckDone( tor, currentNode.recheck_done_cb, currentNode.status_when_done );
     324            continue;
     325        }
     326
     327        tor->runStatus = TR_RUN_CHECKING;
    247328
    248329        /* remove the unchecked pieces from completion... */
     
    253334        tr_inf( "Verifying some pieces of \"%s\"", tor->info.name );
    254335
    255         for( i=0; i<tor->info.pieceCount; ++i )
     336        for( i=0; i<tor->info.pieceCount && !stopCurrent; ++i )
    256337        {
    257338            if( !tr_bitfieldHas( tor->uncheckedPieces, i ) )
     
    262343        }
    263344
    264         tr_bitfieldFree( tor->uncheckedPieces );
    265         tor->uncheckedPieces = NULL;
    266         tor->fastResumeDirty = TRUE;
    267     }
    268 }
    269 
    270 /****
    271 *****  Life Cycle
    272 ****/
    273 
    274 tr_io_t*
    275 tr_ioNew ( tr_torrent_t * tor )
    276 {
    277     tr_io_t * io = tr_calloc( 1, sizeof( tr_io_t ) );
    278     io->tor = tor;
    279     return io;
    280 }
    281 
     345        if( !stopCurrent )
     346        {
     347            tr_bitfieldFree( tor->uncheckedPieces );
     348            tor->uncheckedPieces = NULL;
     349        }
     350        stopCurrent = FALSE;
     351        tr_fastResumeSave( tor );
     352        fireCheckDone( tor, currentNode.recheck_done_cb, currentNode.status_when_done );
     353    }
     354
     355    recheckThread = NULL;
     356}
    282357
    283358void
    284 tr_ioSync( tr_io_t * io )
    285 {
    286     if( io != NULL )
    287     {
    288         int i;
    289         const tr_info_t * info = &io->tor->info;
    290 
    291         for( i=0; i<info->fileCount; ++i )
    292             tr_fdFileClose( io->tor->destination, info->files[i].name );
    293     }
     359tr_ioRecheckAdd( tr_torrent          * tor,
     360                 tr_recheck_done_cb    recheck_done_cb,
     361                 run_status_t          status_when_done )
     362{
     363    if( tor->uncheckedPieces == NULL )
     364    {
     365        fireCheckDone( tor, recheck_done_cb, status_when_done );
     366    }
     367    else
     368    {
     369        struct recheck_node * node;
     370        node = tr_new( struct recheck_node, 1 );
     371        node->torrent = tor;
     372        node->recheck_done_cb = recheck_done_cb;
     373        node->status_when_done = status_when_done;
     374        tr_list_append( &recheckList, node );
     375
     376        tor->runStatus = TR_RUN_CHECKING_WAIT;
     377
     378        if( recheckThread == NULL )
     379            recheckThread = tr_threadNew( recheckThreadFunc, NULL, "recheckThreadFunc" );
     380    }
     381}
     382
     383static int
     384compareRecheckByTorrent( const void * va, const void * vb )
     385{
     386    const struct recheck_node * a = ( const struct recheck_node * ) va;
     387    const struct recheck_node * b = ( const struct recheck_node * ) vb;
     388    return a->torrent - b->torrent;
    294389}
    295390
    296391void
    297 tr_ioClose( tr_io_t * io )
    298 {
    299     if( io != NULL )
    300     {
    301         tr_ioSync( io );
    302         tr_free( io );
    303     }
    304 }
    305 
    306 int
    307 tr_ioHash( tr_io_t * io, int pieceIndex )
    308 {
    309     int i;
    310     int ret;
    311     tr_torrent_t * tor = io->tor;
    312     const int success = !checkPiece( tor, pieceIndex );
    313 
    314     if( success )
    315     {
    316         tr_dbg( "Piece %d hash OK", pieceIndex );
    317         tr_cpPieceAdd( tor->completion, pieceIndex );
    318         ret = TR_OK;
    319     }
    320     else
    321     {
    322         tr_err( "Piece %d hash FAILED", pieceIndex );
    323         tr_cpPieceRem( tor->completion, pieceIndex );
    324         ret = TR_ERROR;
    325     }
    326 
    327     /* Assign blame or credit to peers */
    328     for( i=0; i<tor->peerCount; ++i )
    329         tr_peerBlame( tor->peers[i], pieceIndex, success );
    330 
    331     return ret;
    332 }
     392tr_ioRecheckRemove( tr_torrent * tor )
     393{
     394    if( tor == currentNode.torrent )
     395        stopCurrent = TRUE;
     396    else {
     397        struct recheck_node tmp;
     398        tmp.torrent = tor;
     399        struct recheck_node * node = tr_list_remove( &recheckList, &tmp, compareRecheckByTorrent );
     400        if( node != NULL ) {
     401            fireCheckDone( tor, node->recheck_done_cb, node->status_when_done );
     402            tr_free( node );
     403        }
     404    }
     405}
  • trunk/libtransmission/inout.h

    r2462 r3105  
    2626#define TR_IO_H 1
    2727
    28 typedef struct tr_io_s tr_io_t;
     28struct tr_torrent;
    2929
    30 void tr_ioCheckFiles  ( tr_torrent_t * );
    31 
    32 tr_io_t * tr_ioNew ( tr_torrent_t * );
     30typedef struct tr_io tr_io;
    3331
    3432/***********************************************************************
     
    4038 * TR_ERROR_IO_* otherwise.
    4139 **********************************************************************/
    42 int tr_ioRead  ( tr_io_t *, int index, int begin, int len, uint8_t * );
    43 int tr_ioWrite ( tr_io_t *, int index, int begin, int len, uint8_t * );
     40int tr_ioRead  ( struct tr_torrent*, int index, int begin, int len, uint8_t * );
     41int tr_ioWrite ( struct tr_torrent *, int index, int begin, int len, uint8_t * );
    4442
    45 /***********************************************************************
    46  * tr_ioHash
    47  ***********************************************************************
    48  * Hashes the specified piece and updates the completion accordingly.
    49  **********************************************************************/
    50 int tr_ioHash ( tr_io_t *, int piece );
     43/* hashes the specified piece and updates the completion accordingly. */
     44int tr_ioHash ( tr_torrent*, int piece );
    5145
    52 /***********************************************************************
    53  * tr_ioSync
    54  ***********************************************************************
    55  * Flush all data on disc by closing all files, and update the cache
    56  * file.
    57  **********************************************************************/
    58 void tr_ioSync( tr_io_t * );
     46/* close all the files associated with this torrent*/
     47void tr_ioClose( const tr_torrent * );
    5948
    60 void      tr_ioClose       ( tr_io_t * );
     49/**
     50***
     51**/
     52
     53typedef void (*tr_recheck_done_cb)( tr_torrent * tor );
     54
     55void tr_ioRecheckAdd( tr_torrent          * tor,
     56                      tr_recheck_done_cb    recheck_done_cb,
     57                      run_status_t          status_when_done );
     58
     59void tr_ioRecheckRemove( tr_torrent * tor );
     60
     61/**
     62***
     63**/
    6164
    6265#endif
  • trunk/libtransmission/internal.h

    r2891 r3105  
    4646#endif
    4747
    48 int tr_trackerInfoInit( struct tr_tracker_info_s  * info,
    49                         const char                * address,
    50                         int                         address_len );
     48int tr_trackerInfoInit( struct tr_tracker_info  * info,
     49                        const char              * address,
     50                        int                       address_len );
    5151
    52 void tr_trackerInfoClear( struct tr_tracker_info_s * info );
    53 
    54 struct tr_peer_s;
     52void tr_trackerInfoClear( struct tr_tracker_info * info );
    5553
    5654void tr_peerIdNew ( char* buf, int buflen );
    5755
    58 void tr_torrentResetTransferStats( tr_torrent_t * );
     56void tr_torrentResetTransferStats( tr_torrent * );
    5957
    60 int tr_torrentAddCompact( tr_torrent_t * tor, int from,
    61                            const uint8_t * buf, int count );
    62 int tr_torrentAttachPeer( tr_torrent_t * tor, struct tr_peer_s * );
     58void tr_torrentSetHasPiece( tr_torrent * tor, int pieceIndex, int has );
    6359
    64 void tr_torrentSetHasPiece( tr_torrent_t * tor, int pieceIndex, int has );
     60void tr_torrentLock    ( const tr_torrent * );
     61void tr_torrentUnlock  ( const tr_torrent * );
    6562
    66 void tr_torrentReaderLock    ( const tr_torrent_t * );
    67 void tr_torrentReaderUnlock  ( const tr_torrent_t * );
    68 void tr_torrentWriterLock    ( tr_torrent_t * );
    69 void tr_torrentWriterUnlock  ( tr_torrent_t * );
     63void tr_torrentChangeMyPort  ( tr_torrent *, int port );
    7064
    71 void tr_torrentChangeMyPort  ( tr_torrent_t *, int port );
     65int tr_torrentExists( tr_handle *, const uint8_t * );
     66tr_torrent* tr_torrentFindFromHash( tr_handle *, const uint8_t * );
     67tr_torrent* tr_torrentFindFromObfuscatedHash( tr_handle *, const uint8_t* );
    7268
    7369/* get the index of this piece's first block */
     
    9086
    9187#define tr_block(a,b) _tr_block(tor,a,b)
    92 int _tr_block( const tr_torrent_t * tor, int index, int begin );
     88int _tr_block( const tr_torrent * tor, int index, int begin );
    9389
    9490
    9591typedef enum
    9692{
    97     TR_RUN_CHECKING           = (1<<0), /* checking files' checksums */
    98     TR_RUN_RUNNING            = (1<<1), /* seeding or leeching */
    99     TR_RUN_STOPPING           = (1<<2), /* stopping */
    100     TR_RUN_STOPPING_NET_WAIT  = (1<<3), /* waiting on network -- we're
    101                                            telling tracker we've stopped */
     93    TR_RUN_CHECKING_WAIT      = (1<<0), /* waiting to be checked */
     94    TR_RUN_CHECKING           = (1<<1), /* checking files' checksums */
     95    TR_RUN_RUNNING            = (1<<2), /* seeding or leeching */
     96    TR_RUN_STOPPING           = (1<<3), /* waiting for acknowledgment from tracker */
    10297    TR_RUN_STOPPED            = (1<<4)  /* stopped */
    10398}
     
    106101#define TR_ID_LEN  20
    107102
    108 struct tr_torrent_s
     103struct tr_torrent
    109104{
    110     tr_handle_t               * handle;
    111     tr_info_t                   info;
     105    tr_handle                 * handle;
     106    tr_info                     info;
    112107
    113     tr_speedlimit_t             uploadLimitMode;
    114     tr_speedlimit_t             downloadLimitMode;
    115     struct tr_ratecontrol_s   * upload;
    116     struct tr_ratecontrol_s   * download;
    117     struct tr_ratecontrol_s   * swarmspeed;
     108    tr_speedlimit               uploadLimitMode;
     109    tr_speedlimit               downloadLimitMode;
     110    struct tr_ratecontrol     * upload;
     111    struct tr_ratecontrol     * download;
     112    struct tr_ratecontrol     * swarmspeed;
     113
     114    struct tr_timer           * saveTimer;
    118115
    119116    int                        error;
    120117    char                       errorString[128];
    121118    int                        hasChangedState;
     119
     120    uint8_t                    obfuscatedHash[SHA_DIGEST_LENGTH];
    122121
    123122    uint8_t                  * azId;
     
    137136    int                        blockCountInLastPiece;
    138137   
    139     struct tr_completion_s   * completion;
     138    struct tr_completion     * completion;
    140139
    141140    volatile char              dieFlag;
    142     struct tr_bitfield_s     * uncheckedPieces;
     141    struct tr_bitfield       * uncheckedPieces;
    143142    run_status_t               runStatus;
    144143    run_status_t               runStatusToSave;
    145144    char                       runStatusToSaveIsSet;
    146145    cp_status_t                cpStatus;
    147     struct tr_thread_s       * thread;
    148     struct tr_rwlock_s       * lock;
     146    struct tr_lock           * lock;
    149147
    150     struct tr_tracker_s      * tracker;
     148    struct tr_tracker        * tracker;
    151149    struct tr_publisher_tag  * trackerSubscription;
    152     struct tr_io_s           * io;
    153150    uint64_t                   startDate;
    154151    uint64_t                   stopDate;
    155     char                       ioLoaded;
    156     char                       fastResumeDirty;
    157 
    158     int                        peerCount;
    159     struct tr_peer_s *         peers[TR_MAX_PEER_COUNT];
    160152
    161153    uint64_t                   downloadedCur;
     
    170162
    171163    int8_t                     statCur;
    172     tr_stat_t                  stats[2];
     164    tr_stat                    stats[2];
    173165
    174     tr_torrent_t             * next;
     166    tr_torrent               * next;
    175167};
    176168
    177 struct tr_handle_s
     169struct tr_handle
    178170{
    179     struct tr_event_handle_s * events;
     171    tr_encryption_mode         encryptionMode;
     172
     173    struct tr_event_handle   * events;
    180174
    181175    int                        torrentCount;
    182     tr_torrent_t             * torrentList;
     176    tr_torrent               * torrentList;
    183177
    184178    char                     * tag;
     
    187181    char                       useUploadLimit;
    188182    char                       useDownloadLimit;
    189     struct tr_ratecontrol_s  * upload;
    190     struct tr_ratecontrol_s  * download;
     183    struct tr_ratecontrol    * upload;
     184    struct tr_ratecontrol    * download;
    191185
    192     struct tr_shared_s       * shared;
     186    struct tr_peerMgr        * peerMgr;
     187    struct tr_shared         * shared;
    193188
    194     tr_handle_status_t         stats[2];
     189    tr_handle_status           stats[2];
    195190    int                        statCur;
     191
     192    uint8_t                    isClosed;
    196193
    197194#define TR_AZ_ID_LEN 20
  • trunk/libtransmission/ipcparse.c

    r2391 r3105  
    586586
    587587int
    588 ipc_addinfo( benc_val_t * list, int tor, const tr_info_t * inf, int types )
     588ipc_addinfo( benc_val_t * list, int tor, const tr_info * inf, int types )
    589589{
    590590    benc_val_t * dict, * item, * file, * tier;
     
    728728int
    729729ipc_addstat( benc_val_t * list, int tor,
    730              const tr_stat_t * st, int types )
     730             const tr_stat * st, int types )
    731731{
    732732    benc_val_t  * dict, * item;
  • trunk/libtransmission/ipcparse.h

    r2342 r3105  
    2828#include <inttypes.h>
    2929
    30 /* yay for typedefs, we can't forward declare benc_val_t or tr_info_t
     30/* yay for typedefs, we can't forward declare benc_val_t or tr_info
    3131   like with structs */
    3232#include "bencode.h"
     
    160160uint8_t *    ipc_mkgetinfo( struct ipc_info *, size_t *, enum ipc_msg, int64_t,
    161161                            int, const int * );
    162 int          ipc_addinfo  ( benc_val_t *, int, const tr_info_t *, int );
    163 int          ipc_addstat  ( benc_val_t *, int, const tr_stat_t *, int );
     162int          ipc_addinfo  ( benc_val_t *, int, const tr_info *, int );
     163int          ipc_addstat  ( benc_val_t *, int, const tr_stat *, int );
    164164
    165165/* sets errno to EINVAL on parse error or
  • trunk/libtransmission/list.c

    r2851 r3105  
    1515#include "utils.h"
    1616
    17 static tr_list_t*
     17static tr_list*
    1818node_alloc( void )
    1919{
    20     return tr_new0( tr_list_t, 1 );
     20    return tr_new0( tr_list, 1 );
    2121}
    2222
    2323static void
    24 node_free( tr_list_t* node )
     24node_free( tr_list* node )
    2525{
    2626    tr_free( node );
     
    3232
    3333void
    34 tr_list_free( tr_list_t** list )
     34tr_list_free( tr_list** list )
    3535{
    3636    while( *list )
    3737    {
    38         tr_list_t * node = *list;
     38        tr_list * node = *list;
    3939        *list = (*list)->next;
    4040        node_free( node );
     
    4343
    4444void
    45 tr_list_prepend( tr_list_t ** list, void * data )
     45tr_list_prepend( tr_list ** list, void * data )
    4646{
    47     tr_list_t * node = node_alloc ();
     47    tr_list * node = node_alloc ();
    4848    node->data = data;
    4949    node->next = *list;
     
    5454
    5555void
    56 tr_list_append( tr_list_t ** list, void * data )
     56tr_list_append( tr_list ** list, void * data )
    5757{
    58     tr_list_t * node = node_alloc( );
     58    tr_list * node = node_alloc( );
    5959    node->data = data;
    6060    if( !*list )
    6161        *list = node;
    6262    else {
    63         tr_list_t * l = *list;
     63        tr_list * l = *list;
    6464        while( l->next )
    6565            l = l->next;
     
    7070
    7171void
    72 tr_list_insert_sorted( tr_list_t ** list,
     72tr_list_insert_sorted( tr_list ** list,
    7373                       void       * data,
    7474                       int          compare(const void*,const void*) )
    7575{
    7676    /* find l, the node that we'll insert this data before */
    77     tr_list_t * l;
     77    tr_list * l;
    7878    for( l=*list; l!=NULL; l=l->next ) {
    7979        const int c = (compare)( data, l->data );
     
    8787        tr_list_prepend( list, data );
    8888    else {
    89         tr_list_t * node = node_alloc( );
     89        tr_list * node = node_alloc( );
    9090        node->data = data;
    9191        if( l->prev ) { node->prev = l->prev; node->prev->next = node; }
     
    9696
    9797
    98 tr_list_t*
    99 tr_list_find_data ( tr_list_t * list, const void * data )
     98tr_list*
     99tr_list_find_data ( tr_list * list, const void * data )
    100100{
    101101    for(; list; list=list->next )
     
    106106}
    107107
    108 void
    109 tr_list_remove_data ( tr_list_t ** list, const void * data )
     108static void*
     109tr_list_remove_node ( tr_list ** list, tr_list * node )
    110110{
    111     tr_list_t * node = tr_list_find_data( *list, data );
    112     tr_list_t * prev = node ? node->prev : NULL;
    113     tr_list_t * next = node ? node->next : NULL;
     111    void * data;
     112    tr_list * prev = node ? node->prev : NULL;
     113    tr_list * next = node ? node->next : NULL;
    114114    if( prev ) prev->next = next;
    115115    if( next ) next->prev = prev;
    116116    if( *list == node ) *list = next;
     117    data = node ? node->data : NULL;
    117118    node_free( node );
     119    return data;
    118120}
    119121
    120 tr_list_t*
    121 tr_list_find ( tr_list_t * list , const void * b, TrListCompareFunc func )
     122void*
     123tr_list_pop_front( tr_list ** list )
     124{
     125    void * ret = NULL;
     126    if( *list != NULL )
     127    {
     128        ret = (*list)->data;
     129        tr_list_remove_node( list, *list );
     130    }
     131    return ret;
     132}
     133
     134void*
     135tr_list_remove_data ( tr_list ** list, const void * data )
     136{
     137    return tr_list_remove_node( list, tr_list_find_data( *list, data ) );
     138}
     139
     140void*
     141tr_list_remove( tr_list         ** list,
     142                const void       * b,
     143                TrListCompareFunc  compare_func )
     144{
     145    return tr_list_remove_node( list, tr_list_find( *list, b, compare_func ) );
     146}
     147
     148
     149tr_list*
     150tr_list_find ( tr_list * list , const void * b, TrListCompareFunc func )
    122151{
    123152    for( ; list; list=list->next )
     
    129158
    130159void
    131 tr_list_foreach( tr_list_t * list, TrListForeachFunc func )
     160tr_list_foreach( tr_list * list, TrListForeachFunc func )
    132161{
    133     while( list )
    134     {
     162    while( list != NULL ) {
    135163        func( list->data );
    136164        list = list->next;
    137165    }
    138166}
     167
     168int
     169tr_list_size( const tr_list * list )
     170{
     171    int size = 0;
     172    while( list != NULL ) {
     173        ++size;
     174        list = list->next;
     175    }
     176    return size;
     177}
  • trunk/libtransmission/list.h

    r2849 r3105  
    1414#define TR_LIST_H
    1515
    16 typedef struct tr_list_s
     16typedef struct tr_list
    1717{
    18     void              * data;
    19     struct tr_list_s  * next;
    20     struct tr_list_s  * prev;
     18    void            * data;
     19    struct tr_list  * next;
     20    struct tr_list  * prev;
    2121}
    22 tr_list_t;
     22tr_list;
    2323
    2424typedef int (*TrListCompareFunc)(const void * a, const void * b);
    2525typedef void (*TrListForeachFunc)(void *);
    2626
    27 void        tr_list_free           ( tr_list_t         ** list );
     27int         tr_list_size           ( const tr_list    * list );
    2828
    29 void        tr_list_append         ( tr_list_t         ** list,
    30                                      void               * data );
     29void        tr_list_free           ( tr_list         ** list );
    3130
    32 void        tr_list_prepend        ( tr_list_t         ** list,
    33                                      void               * data );
     31void        tr_list_append         ( tr_list         ** list,
     32                                     void             * data );
    3433
    35 void        tr_list_remove_data    ( tr_list_t         ** list,
    36                                      const void         * data );
     34void        tr_list_prepend        ( tr_list         ** list,
     35                                     void             * data );
    3736
    38 void        tr_list_insert_sorted  ( tr_list_t         ** list,
    39                                      void               * data,
    40                                      TrListCompareFunc    compare_func );
     37void*       tr_list_pop_front      ( tr_list         ** list );
    4138
    42 tr_list_t*  tr_list_find           ( tr_list_t          * list,
    43                                      const void         * b,
    44                                      TrListCompareFunc    compare_func );
     39void*       tr_list_remove_data    ( tr_list         ** list,
     40                                     const void       * data );
    4541
    46 tr_list_t*  tr_list_find_data      ( tr_list_t          * list,
    47                                      const void         * data );
     42void*       tr_list_remove         ( tr_list         ** list,
     43                                     const void       * b,
     44                                     TrListCompareFunc  compare_func );
    4845
    49 void        tr_list_foreach        ( tr_list_t          * list,
    50                                      TrListForeachFunc    foreach_func );
     46void        tr_list_insert_sorted  ( tr_list         ** list,
     47                                     void             * data,
     48                                     TrListCompareFunc  compare_func );
     49
     50tr_list*  tr_list_find           ( tr_list          * list,
     51                                   const void       * b,
     52                                   TrListCompareFunc  compare_func );
     53
     54tr_list*  tr_list_find_data      ( tr_list          * list,
     55                                   const void       * data );
     56
     57void        tr_list_foreach      ( tr_list          * list,
     58                                   TrListForeachFunc  foreach_func );
    5159
    5260#endif /* TR_LIST_H */
  • trunk/libtransmission/makemeta.c

    r2851 r3105  
    2222#include <dirent.h>
    2323
    24 #include "trcompat.h" /* for strlcpy */
     24#include "crypto.h" /* tr_sha1 */
     25#include "trcompat.h" /* strlcpy */
    2526#include "transmission.h"
    26 #include "internal.h" /* for tr_torrent_t */
    2727#include "bencode.h"
    2828#include "makemeta.h"
    2929#include "platform.h" /* threads, locks */
    3030#include "shared.h" /* shared lock */
    31 #include "sha1.h"
    3231#include "utils.h" /* buildpath */
    3332#include "version.h"
     
    232231        assert( bufptr-buf == (int)thisPieceSize );
    233232        assert( pieceRemain == 0 );
    234         SHA1( buf, thisPieceSize, walk );
     233        tr_sha1( buf, walk, thisPieceSize, NULL );
    235234        walk += SHA_DIGEST_LENGTH;
    236235
     
    411410static tr_metainfo_builder_t * queue = NULL;
    412411
    413 static tr_thread_t * workerThread = NULL;
    414 
    415 static tr_lock_t* getQueueLock( tr_handle_t * h )
    416 {
    417     static tr_lock_t * lock = NULL;
     412static tr_thread * workerThread = NULL;
     413
     414static tr_lock* getQueueLock( tr_handle_t * h )
     415{
     416    static tr_lock * lock = NULL;
    418417
    419418    tr_sharedLock( h->shared );
     
    434433
    435434        /* find the next builder to process */
    436         tr_lock_t * lock = getQueueLock ( handle );
     435        tr_lock * lock = getQueueLock ( handle );
    437436        tr_lockLock( lock );
    438437        if( queue != NULL ) {
     
    459458                 int                      isPrivate )
    460459{
    461     tr_lock_t * lock;
     460    tr_lock * lock;
    462461
    463462    builder->abortFlag = 0;
  • trunk/libtransmission/metainfo.c

    r2857 r3105  
    3434#include "transmission.h"
    3535#include "bencode.h"
     36#include "crypto.h" /* tr_sha1 */
    3637#include "http.h" /* tr_httpParseUrl */
    3738#include "metainfo.h"
    3839#include "platform.h"
    39 #include "sha1.h"
    4040#include "utils.h"
    4141
     
    4545 * Local prototypes
    4646 **********************************************************************/
    47 static int realparse( tr_info_t * inf, const uint8_t * buf, size_t len );
     47static int realparse( tr_info * inf, const uint8_t * buf, size_t len );
    4848static void savedname( char * name, size_t len, const char * hash,
    4949                       const char * tag );
     
    5353static int getfile( char * buf, int size,
    5454                    const char * prefix, benc_val_t * name );
    55 static int getannounce( tr_info_t * inf, benc_val_t * meta );
     55static int getannounce( tr_info * inf, benc_val_t * meta );
    5656static char * announceToScrape( const char * announce );
    57 static int parseFiles( tr_info_t * inf, benc_val_t * name,
     57static int parseFiles( tr_info * inf, benc_val_t * name,
    5858                       benc_val_t * files, benc_val_t * length );
    5959
     
    6464 **********************************************************************/
    6565int
    66 tr_metainfoParseFile( tr_info_t * inf, const char * tag,
     66tr_metainfoParseFile( tr_info * inf, const char * tag,
    6767                      const char * path, int save )
    6868{
     
    103103
    104104int
    105 tr_metainfoParseData( tr_info_t * inf, const char * tag,
     105tr_metainfoParseData( tr_info * inf, const char * tag,
    106106                      const uint8_t * data, size_t size, int save )
    107107{
     
    124124
    125125int
    126 tr_metainfoParseHash( tr_info_t * inf, const char * tag, const char * hash )
     126tr_metainfoParseHash( tr_info * inf, const char * tag, const char * hash )
    127127{
    128128    struct stat sb;
     
    173173
    174174static int
    175 realparse( tr_info_t * inf, const uint8_t * buf, size_t size )
     175realparse( tr_info * inf, const uint8_t * buf, size_t size )
    176176{
    177177    benc_val_t   meta, * beInfo, * val, * val2;
     
    193193        return TR_EINVALID;
    194194    }
    195     SHA1( (uint8_t *) beInfo->begin,
    196           (long) beInfo->end - (long) beInfo->begin, inf->hash );
     195
     196    tr_sha1( inf->hash, beInfo->begin, beInfo->end - beInfo->begin, NULL );
     197
    197198    for( i = 0; i < SHA_DIGEST_LENGTH; i++ )
    198199    {
     
    255256    inf->pieceCount = val->val.s.i / SHA_DIGEST_LENGTH;
    256257
    257     inf->pieces = calloc ( inf->pieceCount, sizeof(tr_piece_t) );
     258    inf->pieces = calloc ( inf->pieceCount, sizeof(tr_piece) );
    258259
    259260    for ( i=0; i<inf->pieceCount; ++i )
     
    308309}
    309310
    310 void tr_metainfoFree( tr_info_t * inf )
     311void tr_metainfoFree( tr_info * inf )
    311312{
    312313    int i, j;
     
    323324    tr_free( inf->trackerList );
    324325
    325     memset( inf, '\0', sizeof(tr_info_t) );
     326    memset( inf, '\0', sizeof(tr_info) );
    326327}
    327328
     
    382383}
    383384
    384 static int getannounce( tr_info_t * inf, benc_val_t * meta )
     385static int getannounce( tr_info * inf, benc_val_t * meta )
    385386{
    386387    benc_val_t        * val, * subval, * urlval;
    387388    char              * address, * announce;
    388389    int                 ii, jj, port, random, subcount;
    389     tr_tracker_info_t * sublist;
     390    tr_tracker_info  * sublist;
    390391    void * swapping;
    391392
     
    412413            for( jj = 0; jj < subval->val.l.count; jj++ )
    413414            {
    414                 tr_tracker_info_t tmp;
     415                tr_tracker_info tmp;
    415416
    416417                urlval = &subval->val.l.vals[jj];
     
    559560
    560561int
    561 tr_trackerInfoInit( tr_tracker_info_t  * info,
    562                     const char         * address,
    563                     int                  address_len )
     562tr_trackerInfoInit( tr_tracker_info  * info,
     563                    const char       * address,
     564                    int                address_len )
    564565{
    565566    int ret = tr_httpParseUrl( address, address_len,
     
    574575
    575576void
    576 tr_trackerInfoClear( tr_tracker_info_t * info )
     577tr_trackerInfoClear( tr_tracker_info * info )
    577578{
    578579    tr_free( info->address );
    579580    tr_free( info->announce );
    580581    tr_free( info->scrape );
    581     memset( info, '\0', sizeof(tr_tracker_info_t) );
     582    memset( info, '\0', sizeof(tr_tracker_info) );
    582583}
    583584
     
    691692
    692693static int
    693 parseFiles( tr_info_t * inf, benc_val_t * name,
     694parseFiles( tr_info * inf, benc_val_t * name,
    694695            benc_val_t * files, benc_val_t * length )
    695696{
  • trunk/libtransmission/metainfo.h

    r2207 r3105  
    2828#include "transmission.h"
    2929
    30 int tr_metainfoParseFile( tr_info_t *, const char * tag,
     30int tr_metainfoParseFile( tr_info *, const char * tag,
    3131                          const char * path, int save );
    32 int tr_metainfoParseData( tr_info_t *, const char * tag,
     32int tr_metainfoParseData( tr_info *, const char * tag,
    3333                          const uint8_t * data, size_t size, int save );
    34 int tr_metainfoParseHash( tr_info_t *, const char * tag, const char * hash );
    35 void tr_metainfoFree( tr_info_t * inf );
     34int tr_metainfoParseHash( tr_info *, const char * tag, const char * hash );
     35void tr_metainfoFree( tr_info * inf );
    3636void tr_metainfoRemoveSaved( const char * hashString, const char * tag );
    3737
  • trunk/libtransmission/net.c

    r2614 r3105  
    5858/***********************************************************************
    5959 * DNS resolution
    60  **********************************************************************/
    61 
    62 /***********************************************************************
    63  * tr_netResolve
    64  ***********************************************************************
     60 *
    6561 * Synchronous "resolution": only works with character strings
    6662 * representing numbers expressed in the Internet standard `.' notation.
     
    7167    addr->s_addr = inet_addr( address );
    7268    return ( addr->s_addr == 0xFFFFFFFF );
    73 }
    74 
    75 static tr_thread_t  * resolveThread;
    76 static tr_lock_t    * resolveLock;
    77 static tr_cond_t    * resolveCond;
    78 static volatile int   resolveDie;
    79 static tr_resolve_t * resolveQueue;
    80 
    81 static void resolveRelease ( tr_resolve_t * );
    82 static void resolveFunc    ( void * );
    83 
    84 struct tr_resolve_s
    85 {
    86     tr_tristate_t  status;
    87     char           * address;
    88     struct in_addr addr;
    89 
    90     int            refcount;
    91     tr_resolve_t   * next;
    92 };
    93 
    94 /***********************************************************************
    95  * tr_netResolveThreadInit
    96  ***********************************************************************
    97  * Initializes the static variables used for resolution and launch the
    98  * gethostbyname thread.
    99  **********************************************************************/
    100 void tr_netResolveThreadInit( void )
    101 {
    102     resolveDie   = 0;
    103     resolveQueue = NULL;
    104     resolveLock = tr_lockNew( );
    105     resolveCond = tr_condNew( );
    106     resolveThread = tr_threadNew( resolveFunc, NULL, "resolve" );
    107 }
    108 
    109 /***********************************************************************
    110  * tr_netResolveThreadClose
    111  ***********************************************************************
    112  * Notices the gethostbyname thread that is should terminate. Doesn't
    113  * wait until it does, in case it is stuck in a resolution: we let it
    114  * die and clean itself up.
    115  **********************************************************************/
    116 void tr_netResolveThreadClose( void )
    117 {
    118     tr_lockLock( resolveLock );
    119     resolveDie = 1;
    120     tr_lockUnlock( resolveLock );
    121     tr_condSignal( resolveCond );
    122     tr_wait( 200 );
    123 }
    124 
    125 /***********************************************************************
    126  * tr_netResolveInit
    127  ***********************************************************************
    128  * Adds an address to the resolution queue.
    129  **********************************************************************/
    130 tr_resolve_t * tr_netResolveInit( const char * address )
    131 {
    132     tr_resolve_t * r = tr_new0( tr_resolve_t, 1 );
    133     r->status   = TR_NET_WAIT;
    134     r->address  = strdup( address );
    135     r->refcount = 2;
    136     r->next     = NULL;
    137 
    138     tr_lockLock( resolveLock );
    139     if( !resolveQueue )
    140     {
    141         resolveQueue = r;
    142     }
    143     else
    144     {
    145         tr_resolve_t * iter;
    146         for( iter = resolveQueue; iter->next; iter = iter->next );
    147         iter->next = r;
    148     }
    149     tr_lockUnlock( resolveLock );
    150     tr_condSignal( resolveCond );
    151 
    152     return r;
    153 }
    154 
    155 /***********************************************************************
    156  * tr_netResolvePulse
    157  ***********************************************************************
    158  * Checks the current status of a resolution.
    159  **********************************************************************/
    160 tr_tristate_t tr_netResolvePulse( tr_resolve_t * r, struct in_addr * addr )
    161 {
    162     tr_tristate_t ret;
    163 
    164     tr_lockLock( resolveLock );
    165     ret = r->status;
    166     if( ret == TR_NET_OK )
    167     {
    168         *addr = r->addr;
    169     }
    170     tr_lockUnlock( resolveLock );
    171 
    172     return ret;
    173 }
    174 
    175 /***********************************************************************
    176  * tr_netResolveClose
    177  ***********************************************************************
    178  *
    179  **********************************************************************/
    180 void tr_netResolveClose( tr_resolve_t * r )
    181 {
    182     resolveRelease( r );
    183 }
    184 
    185 /***********************************************************************
    186  * resolveRelease
    187  ***********************************************************************
    188  * The allocated tr_resolve_t structures should be freed when
    189  * tr_netResolveClose was called *and* it was removed from the queue.
    190  * This can happen in any order, so we use a refcount to know we can
    191  * take it out.
    192  **********************************************************************/
    193 static void resolveRelease( tr_resolve_t * r )
    194 {
    195     if( --r->refcount < 1 )
    196     {
    197         free( r->address );
    198         free( r );
    199     }
    200 }
    201 
    202 /***********************************************************************
    203  * resolveFunc
    204  ***********************************************************************
    205  * Keeps waiting for addresses to resolve, and removes them from the
    206  * queue once resolution is done.
    207  **********************************************************************/
    208 static void resolveFunc( void * arg UNUSED )
    209 {
    210     tr_resolve_t * r;
    211     struct hostent * host;
    212 
    213     tr_lockLock( resolveLock );
    214 
    215     while( !resolveDie )
    216     {
    217         if( !( r = resolveQueue ) )
    218         {
    219             tr_condWait( resolveCond, resolveLock );
    220             continue;
    221         }
    222 
    223         /* Blocking resolution */
    224         tr_lockUnlock( resolveLock );
    225         host = gethostbyname( r->address );
    226         tr_lockLock( resolveLock );
    227 
    228         if( host )
    229         {
    230             memcpy( &r->addr, host->h_addr, host->h_length );
    231             r->status = TR_NET_OK;
    232         }
    233         else
    234         {
    235             r->status = TR_NET_ERROR;
    236         }
    237        
    238         resolveQueue = r->next;
    239         resolveRelease( r );
    240     }
    241 
    242     /* Clean up  */
    243     tr_lockUnlock( resolveLock );
    244     tr_lockFree( resolveLock );
    245     resolveLock = NULL;
    246     while( ( r = resolveQueue ) )
    247     {
    248         resolveQueue = r->next;
    249         resolveRelease( r );
    250     }
    25169}
    25270
     
    470288}
    471289
    472 void tr_netClose( int s )
     290void
     291tr_netClose( int s )
    473292{
    474293    tr_fdSocketClose( s );
    475294}
    476295
    477 void tr_netNtop( const struct in_addr * addr, char * buf, int len )
     296void
     297tr_netNtop( const struct in_addr * addr, char * buf, int len )
    478298{
    479299    const uint8_t * cast;
  • trunk/libtransmission/net.h

    r2615 r3105  
    6868int tr_netResolve( const char *, struct in_addr * );
    6969
    70 typedef struct tr_resolve_s tr_resolve_t;
    71 void           tr_netResolveThreadInit( void );
    72 void           tr_netResolveThreadClose( void );
    73 tr_resolve_t * tr_netResolveInit( const char * address );
    74 tr_tristate_t  tr_netResolvePulse( tr_resolve_t *, struct in_addr * );
    75 void           tr_netResolveClose( tr_resolve_t * );
    76 
    7770
    7871/***********************************************************************
  • trunk/libtransmission/peer.c

    r2991 r3105  
    175175struct tr_peer_s
    176176{
    177     tr_torrent_t      * tor;
     177    tr_torrent        * tor;
    178178
    179179    struct in_addr      addr;
     
    215215
    216216    /* The pieces that the peer has */
    217     tr_bitfield_t     * bitfield;
     217    tr_bitfield       * bitfield;
    218218
    219219    /* blocks we've requested from this peer */
    220     tr_bitfield_t     * reqfield;
     220    tr_bitfield       * reqfield;
    221221    int                 pieceCount;
    222222    float               progress;
     
    226226    int                 banned;
    227227    /* The pieces that the peer is contributing to */
    228     tr_bitfield_t     * blamefield;
     228    tr_bitfield       * blamefield;
    229229    /* The bad pieces that the peer has contributed to */
    230     tr_bitfield_t     * banfield;
     230    tr_bitfield       * banfield;
    231231
    232232    uint8_t           * buf;
     
    250250    int                 inLength;
    251251
    252     tr_list_t         * outRequests;
     252    tr_list           * outRequests;
    253253    uint64_t            outDate;
    254254
    255     tr_ratecontrol_t  * download;
    256     tr_ratecontrol_t  * upload;
     255    tr_ratecontrol    * download;
     256    tr_ratecontrol    * upload;
    257257
    258258    char              * client;
     
    290290    const uint32_t u = htonl( a );
    291291    memcpy ( p, &u, sizeof( uint32_t ) );
    292 }
    293 
    294 static const char* getPeerId( void )
    295 {
    296     static char * peerId = NULL;
    297     if( !peerId ) {
    298         peerId = tr_new0( char, TR_ID_LEN + 1 );
    299         tr_peerIdNew( peerId, TR_ID_LEN + 1 );
    300     }
    301     return peerId;
    302292}
    303293
     
    354344void tr_peerDestroy( tr_peer_t * peer )
    355345{
    356     tr_torrent_t * tor = peer->tor;
     346    tr_torrent * tor = peer->tor;
    357347    tr_request_t * r;
    358348    int i, block;
     
    424414}
    425415
    426 void tr_peerSetTorrent( tr_peer_t * peer, tr_torrent_t * tor )
     416void tr_peerSetTorrent( tr_peer_t * peer, tr_torrent * tor )
    427417{
    428418    peer->tor = tor;
     
    436426int tr_peerRead( tr_peer_t * peer )
    437427{
    438     tr_torrent_t * tor = peer->tor;
     428    tr_torrent * tor = peer->tor;
    439429    int ret;
    440430    uint64_t date;
     
    543533int tr_peerPulse( tr_peer_t * peer )
    544534{
    545     tr_torrent_t * tor = peer->tor;
     535    tr_torrent * tor = peer->tor;
    546536    int ret, size;
    547537    uint8_t * p;
     
    581571    {
    582572        uint8_t buf[HANDSHAKE_SIZE];
    583         const tr_info_t * inf;
     573        const tr_info * inf;
    584574
    585575        inf = tr_torrentInfo( tor );
     
    794784}
    795785
    796 int tr_peerIsFrom( const tr_peer_t * peer )
     786int tr_peerGetFrom( const tr_peer_t * peer )
    797787{
    798788    return peer->from;
     
    886876void tr_peerBlame( tr_peer_t * peer, int piece, int success )
    887877{
    888     tr_torrent_t * tor = peer->tor;
     878    tr_torrent * tor = peer->tor;
    889879
    890880    if( !peer->blamefield || !tr_bitfieldHas( peer->blamefield, piece ) )
     
    927917}
    928918
    929 int tr_peerGetConnectable( const tr_torrent_t * tor, uint8_t ** _buf )
     919int tr_peerGetConnectable( const tr_torrent * tor, uint8_t ** _buf )
    930920{
    931921    int count = 0;
     
    970960tr_peerPieceIsCorrupt( tr_peer_t * peer, int pieceIndex )
    971961{
    972     tr_torrent_t * tor = peer->tor;
     962    tr_torrent * tor = peer->tor;
    973963
    974964    const uint64_t byteCount = tr_torPieceCountBytes( tor, pieceIndex );
     
    987977tr_peerSentBlockToUs( tr_peer_t * peer, int byteCount )
    988978{
    989     tr_torrent_t * tor = peer->tor;
     979    tr_torrent * tor = peer->tor;
    990980
    991981    assert( byteCount >= 0 );
     
    1003993tr_peerGotBlockFromUs ( tr_peer_t * peer, int byteCount )
    1004994{
    1005     tr_torrent_t * tor = peer->tor;
     995    tr_torrent * tor = peer->tor;
    1006996
    1007997    assert( byteCount >= 0 );
     
    10171007
    10181008static void
    1019 tr_torrentSwiftPulse ( tr_torrent_t * tor )
     1009tr_torrentSwiftPulse ( tr_torrent * tor )
    10201010{
    10211011    /* Preferred # of seconds for the request queue's turnaround time.
     
    10921082    if( lastPulseTime + SWIFT_REFRESH_INTERVAL_SEC <= time( NULL ) )
    10931083    {
    1094         tr_torrent_t * tor;
     1084        tr_torrent * tor;
    10951085        for( tor=h->torrentList; tor; tor=tor->next )
    10961086            tr_torrentSwiftPulse( tor );
  • trunk/libtransmission/peer.h

    r2573 r3105  
    3535const char *tr_peerClient          ( tr_peer_t * );
    3636void        tr_peerSetPrivate      ( tr_peer_t *, int );
    37 void        tr_peerSetTorrent      ( tr_peer_t *, struct tr_torrent_s * );
     37void        tr_peerSetTorrent      ( tr_peer_t *, struct tr_torrent * );
    3838void        tr_peerSentBlockToUs   ( tr_peer_t *, int byteCount );
    3939void        tr_peerGotBlockFromUs  ( tr_peer_t *, int byteCount );
     
    4343int         tr_peerPulse           ( tr_peer_t * );
    4444int         tr_peerIsConnected     ( const tr_peer_t * );
    45 int         tr_peerIsFrom          ( const tr_peer_t * );
     45int         tr_peerGetFrom         ( const tr_peer_t * );
    4646int         tr_peerTimesChoked     ( const tr_peer_t * );
    4747int         tr_peerIsChokingUs     ( const tr_peer_t * );
     
    6161void        tr_peerBlame           ( tr_peer_t *, int piece, int success );
    6262struct in_addr * tr_peerAddress    ( tr_peer_t * );
    63 int         tr_peerGetConnectable  ( const struct tr_torrent_s *, uint8_t ** );
     63int         tr_peerGetConnectable  ( const struct tr_torrent *, uint8_t ** );
    6464
    6565void        tr_swiftPulse          ( tr_handle_t * );
  • trunk/libtransmission/peeraz.h

    r2911 r3105  
    9898
    9999static uint8_t *
    100 makeAZHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * buflen )
     100makeAZHandshake( tr_torrent * tor, tr_peer_t * peer, int * buflen )
    101101{
    102102    char       * buf;
     
    225225
    226226static int
    227 makeAZPex( tr_torrent_t * tor, tr_peer_t * peer, char ** buf, int * len )
     227makeAZPex( tr_torrent * tor, tr_peer_t * peer, char ** buf, int * len )
    228228{
    229229    benc_val_t val;
     
    236236
    237237static int
    238 sendAZHandshake( tr_torrent_t * tor, tr_peer_t * peer )
     238sendAZHandshake( tr_torrent * tor, tr_peer_t * peer )
    239239{
    240240    uint8_t * buf;
     
    373373{
    374374    benc_val_t      val, * sub, * sub2, * dict, * subsub;
    375     tr_bitfield_t * msgs;
     375    tr_bitfield  * msgs;
    376376    int             ii, idx, newclient;
    377377    char          * client;
     
    493493
    494494static int
    495 parseAZPex( tr_torrent_t * tor, tr_peer_t * peer, uint8_t * buf, int len )
    496 {
    497     tr_info_t * info = &tor->info;
     495parseAZPex( tr_torrent * tor, tr_peer_t * peer, uint8_t * buf, int len )
     496{
     497    tr_info * info = &tor->info;
    498498    benc_val_t  val, * list, * pair;
    499499    int         ii, used;
  • trunk/libtransmission/peerext.h

    r2781 r3105  
    2727
    2828static int
    29 makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer,
     29makeCommonPex( tr_torrent * tor, tr_peer_t * peer,
    3030               int ( *peerfunc )( tr_peertree_t *, benc_val_t * ),
    3131               const char * extrakey, benc_val_t * extraval,
     
    123123
    124124static char *
    125 makeExtendedHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * len )
     125makeExtendedHandshake( tr_torrent * tor, tr_peer_t * peer, int * len )
    126126{
    127127    benc_val_t val, * msgsval;
     
    206206
    207207static int
    208 makeUTPex( tr_torrent_t * tor, tr_peer_t * peer, char ** buf, int * len )
     208makeUTPex( tr_torrent * tor, tr_peer_t * peer, char ** buf, int * len )
    209209{
    210210    benc_val_t val;
     
    300300
    301301static int
    302 parseUTPex( tr_torrent_t * tor, tr_peer_t * peer, uint8_t * buf, int len )
     302parseUTPex( tr_torrent * tor, tr_peer_t * peer, uint8_t * buf, int len )
    303303{
    304304    benc_val_t val, * sub;
     
    327327    if( NULL != sub && TYPE_STR == sub->type && 0 == sub->val.s.i % 6 )
    328328    {
     329#if 0
    329330        used = tr_torrentAddCompact( tor, TR_PEER_FROM_PEX,
    330331                                     ( uint8_t * )sub->val.s.s,
     
    332333        peer_dbg( "GET  extended-pex, got %i peers, used %i",
    333334                  sub->val.s.i / 6, used );
     335#endif
    334336    }
    335337    else
  • trunk/libtransmission/peermessages.h

    r2746 r3105  
    106106
    107107static uint8_t *
    108 blockPending( tr_torrent_t  * tor,
    109               tr_peer_t     * peer,
    110               int           * size )
     108blockPending( tr_torrent  * tor,
     109              tr_peer_t   * peer,
     110              int         * size )
    111111{
    112112    if( !peer->outBlockLoaded ) /* we need to load the block for the next request */
     
    144144        buf += 4;
    145145
    146         tr_ioRead( tor->io, r->index, r->begin, r->length, buf );
     146        tr_ioRead( tor, r->index, r->begin, r->length, buf );
    147147
    148148        peer_dbg( "SEND piece %d/%d (%d bytes)",
     
    275275 *  - bitfield     (X bytes)
    276276 **********************************************************************/
    277 static void sendBitfield( tr_torrent_t * tor, tr_peer_t * peer )
     277static void sendBitfield( tr_torrent * tor, tr_peer_t * peer )
    278278{
    279279    uint8_t             * p;
    280     const tr_bitfield_t * bitfield;
     280    const tr_bitfield  * bitfield;
    281281
    282282    bitfield = tr_cpPieceBitfield( tor->completion );
     
    293293 *
    294294 **********************************************************************/
    295 static void sendRequest( tr_torrent_t * tor, tr_peer_t * peer, int block )
    296 {
    297     tr_info_t * inf = &tor->info;
     295static void sendRequest( tr_torrent * tor, tr_peer_t * peer, int block )
     296{
     297    tr_info * inf = &tor->info;
    298298    tr_request_t * r;
    299299    uint8_t * p;
     
    344344 *
    345345 **********************************************************************/
    346 static void broadcastCancel( tr_torrent_t * tor, int index, int begin,
     346static void broadcastCancel( tr_torrent * tor, int index, int begin,
    347347                             int length )
    348348{
     
    386386 *  - data         (X bytes)
    387387 **********************************************************************/
    388 static int sendExtended( tr_torrent_t * tor, tr_peer_t * peer, int id )
     388static int sendExtended( tr_torrent * tor, tr_peer_t * peer, int id )
    389389{
    390390    uint8_t * p;
     
    434434 *
    435435 **********************************************************************/
    436 static int sendAZPex( tr_torrent_t * tor, tr_peer_t * peer )
     436static int sendAZPex( tr_torrent * tor, tr_peer_t * peer )
    437437{
    438438    uint8_t * p;
  • trunk/libtransmission/peerparse.h

    r2891 r3105  
    3333 **********************************************************************/
    3434
    35 static int parseChoke( tr_torrent_t  * tor,
    36                        tr_peer_t     * peer,
    37                        int             len,
    38                        int             choking )
     35static int parseChoke( tr_torrent  * tor,
     36                       tr_peer_t   * peer,
     37                       int           len,
     38                       int           choking )
    3939{
    4040    tr_request_t * r;
     
    102102 *
    103103 **********************************************************************/
    104 static int parseHave( tr_torrent_t * tor, tr_peer_t * peer,
    105                              uint8_t * p, int len )
    106 {
    107     tr_info_t * inf = &tor->info;
     104static int parseHave( tr_torrent * tor, tr_peer_t * peer,
     105                      uint8_t * p, int len )
     106{
     107    tr_info * inf = &tor->info;
    108108    uint32_t piece;
    109109
     
    140140}
    141141
    142 static int parseBitfield( tr_torrent_t * tor, tr_peer_t * peer,
    143                                  uint8_t * p, int len )
    144 {
    145     tr_info_t * inf = &tor->info;
     142static int parseBitfield( tr_torrent * tor, tr_peer_t * peer,
     143                          uint8_t * p, int len )
     144{
     145    tr_info * inf = &tor->info;
    146146    int bitfieldSize;
    147147    int i;
     
    195195}
    196196
    197 static int parseRequest( tr_torrent_t * tor, tr_peer_t * peer,
    198                                 uint8_t * p, int len )
    199 {
    200     tr_info_t * inf = &tor->info;
     197static int parseRequest( tr_torrent * tor, tr_peer_t * peer,
     198                         uint8_t * p, int len )
     199{
     200    tr_info * inf = &tor->info;
    201201    int index, begin, length;
    202202    tr_request_t * r;
     
    282282}
    283283
    284 static int parsePiece( tr_torrent_t * tor, tr_peer_t * peer,
    285                               uint8_t * p, int len )
    286 {
    287     tr_info_t * inf = &tor->info;
     284static int parsePiece( tr_torrent * tor, tr_peer_t * peer,
     285                       uint8_t * p, int len )
     286{
     287    tr_info * inf = &tor->info;
    288288    int index, begin, block, i, ret;
    289289
     
    335335
    336336    /* Write to disk */
    337     if( ( ret = tr_ioWrite( tor->io, index, begin, len - 8, &p[8] ) ) )
     337    if( ( ret = tr_ioWrite( tor, index, begin, len - 8, &p[8] ) ) )
    338338    {
    339339        return ret;
     
    380380}
    381381
    382 static int parseCancel( tr_torrent_t * tor, tr_peer_t * peer,
    383                                uint8_t * p, int len )
    384 {
    385     tr_info_t * inf = &tor->info;
     382static int parseCancel( tr_torrent * tor, tr_peer_t * peer,
     383                        uint8_t * p, int len )
     384{
     385    tr_info * inf = &tor->info;
    386386    int index, begin, length;
    387387    tr_request_t req;
    388     tr_list_t * l;
     388    tr_list * l;
    389389
    390390    if( len != 12 )
     
    475475}
    476476
    477 static int parseMessage( tr_torrent_t * tor, tr_peer_t * peer,
    478                                 int id, uint8_t * p, int len )
     477static int parseMessage( tr_torrent * tor, tr_peer_t * peer,
     478                         int id, uint8_t * p, int len )
    479479{
    480480    int extid;
     
    598598}
    599599
    600 static int parseHandshake( tr_torrent_t * tor, tr_peer_t * peer )
    601 {
    602     tr_info_t * inf = &tor->info;
     600static int parseHandshake( tr_torrent * tor, tr_peer_t * peer )
     601{
     602    tr_info * inf = &tor->info;
    603603    int         ii, extmsgs, azproto;
    604604    char      * dbgsup, * dbgwant;
     
    695695}
    696696
    697 static int sendInitial( tr_torrent_t * tor, tr_peer_t * peer )
     697static int sendInitial( tr_torrent * tor, tr_peer_t * peer )
    698698{
    699699    if( PEER_STATUS_CONNECTED != peer->status )
     
    716716}
    717717
    718 static int parseBuf( tr_torrent_t * tor, tr_peer_t * peer )
     718static int parseBuf( tr_torrent * tor, tr_peer_t * peer )
    719719{
    720720    int       len, ret, msgid;
  • trunk/libtransmission/peerutils.h

    r2672 r3105  
    3939{
    4040    int ret;
    41     tr_torrent_t * tor = peer->tor;
     41    tr_torrent * tor = peer->tor;
    4242    const uint64_t now = tr_date( );
    4343    const uint64_t idleTime = now - peer->date;
     
    138138}
    139139
    140 static int isPieceInteresting( const tr_torrent_t  * tor,
    141                                const tr_peer_t     * peer,
    142                                int                   piece )
     140static int isPieceInteresting( const tr_torrent  * tor,
     141                               const tr_peer_t   * peer,
     142                               int                 piece )
    143143{
    144144    if( tor->info.pieces[piece].dnd ) /* we don't want it */
     
    163163 * haven't completed, or 0 otherwise.
    164164 **********************************************************************/
    165 static int isInteresting( const tr_torrent_t * tor, const tr_peer_t * peer )
     165static int isInteresting( const tr_torrent * tor, const tr_peer_t * peer )
    166166{
    167167    int i;
    168     const tr_bitfield_t * bitfield = tr_cpPieceBitfield( tor->completion );
     168    const tr_bitfield  * bitfield = tr_cpPieceBitfield( tor->completion );
    169169
    170170    if( !peer->bitfield )
     
    184184
    185185static void
    186 updateInterest( tr_torrent_t * tor, tr_peer_t * peer )
     186updateInterest( tr_torrent * tor, tr_peer_t * peer )
    187187{
    188188    const int i = !!isInteresting( tor, peer );
     
    224224}
    225225
    226 static int* getPreferredPieces( const tr_torrent_t  * tor,
    227                                 const tr_peer_t     * peer,
    228                                 int                 * pieceCount,
    229                                 int                 * isEndgame )
    230 {
    231     const tr_info_t * inf = &tor->info;
     226static int* getPreferredPieces( const tr_torrent  * tor,
     227                                const tr_peer_t   * peer,
     228                                int               * pieceCount,
     229                                int               * isEndgame )
     230{
     231    const tr_info * inf = &tor->info;
    232232
    233233    int i;
  • trunk/libtransmission/platform.c

    r2975 r3105  
    5757***/
    5858
    59 struct tr_thread_s
     59struct tr_thread
    6060{
    6161    void          (* func ) ( void * );
    6262    void           * arg;
    63     char           * name;
     63    const char     * name;
    6464
    6565#ifdef __BEOS__
     
    8383ThreadFunc( void * _t )
    8484{
    85     tr_thread_t * t = _t;
    86     char* name = tr_strdup( t->name );
     85    tr_thread * t = _t;
     86    const char * name = t->name;
    8787
    8888#ifdef __BEOS__
     
    9696    tr_dbg( "Thread '%s' exited", name );
    9797
    98     tr_free( name );
    99 
    10098#ifdef WIN32
    10199    _endthreadex( 0 );
     
    104102}
    105103
    106 tr_thread_t *
     104tr_thread *
    107105tr_threadNew( void (*func)(void *),
    108106              void * arg,
    109107              const char * name )
    110108{
    111     tr_thread_t * t = tr_new0( tr_thread_t, 1 );
     109    tr_thread * t = tr_new0( tr_thread, 1 );
    112110    t->func = func;
    113111    t->arg  = arg;
    114     t->name = tr_strdup( name );
     112    t->name = name;
    115113
    116114#ifdef __BEOS__
     
    127125
    128126int
    129 tr_amInThread ( const tr_thread_t * t )
    130 {
    131     int ret;
    132 #ifdef __BEOS__
    133     ret = find_thread(NULL) == t->thread;
    134 #elif defined(WIN32)
    135     ret = GetCurrentThreadId() == t->thread_id;
    136 #else
    137     ret = pthread_equal( t->thread, pthread_self( ) );
    138 #endif
    139     return ret;
     127tr_amInThread ( const tr_thread * t )
     128{
     129#ifdef __BEOS__
     130    return find_thread(NULL) == t->thread;
     131#elif defined(WIN32)
     132    return GetCurrentThreadId() == t->thread_id;
     133#else
     134    return pthread_equal( t->thread, pthread_self( ) );
     135#endif
    140136}
    141137   
    142138void
    143 tr_threadJoin( tr_thread_t * t )
     139tr_threadJoin( tr_thread * t )
    144140{
    145141    if( t != NULL )
     
    156152
    157153        tr_dbg( "Thread '%s' joined", t->name );
    158         tr_free( t->name );
    159154        t->name = NULL;
    160155        t->func = NULL;
     
    167162***/
    168163
    169 struct tr_lock_s
     164struct tr_lock
    170165{
    171166#ifdef __BEOS__
     
    178173};
    179174
    180 tr_lock_t*
     175tr_lock*
    181176tr_lockNew( void )
    182177{
    183     tr_lock_t * l = tr_new0( tr_lock_t, 1 );
     178    tr_lock * l = tr_new0( tr_lock, 1 );
    184179
    185180#ifdef __BEOS__
     
    195190
    196191void
    197 tr_lockFree( tr_lock_t * l )
     192tr_lockFree( tr_lock * l )
    198193{
    199194#ifdef __BEOS__
     
    208203
    209204int
    210 tr_lockTryLock( tr_lock_t * l ) /* success on zero! */
     205tr_lockTryLock( tr_lock * l ) /* success on zero! */
    211206{
    212207#ifdef __BEOS__
     
    220215
    221216void
    222 tr_lockLock( tr_lock_t * l )
     217tr_lockLock( tr_lock * l )
    223218{
    224219#ifdef __BEOS__
     
    232227
    233228void
    234 tr_lockUnlock( tr_lock_t * l )
     229tr_lockUnlock( tr_lock * l )
    235230{
    236231#ifdef __BEOS__
     
    241236    pthread_mutex_unlock( &l->lock );
    242237#endif
    243 }
    244 
    245 /***
    246 ****  RW LOCK
    247 ***/
    248 
    249 struct tr_rwlock_s
    250 {
    251     tr_lock_t * lock;
    252     tr_cond_t * readCond;
    253     tr_cond_t * writeCond;
    254     size_t readCount;
    255     size_t wantToRead;
    256     size_t wantToWrite;
    257     int haveWriter;
    258 };
    259 
    260 static void
    261 tr_rwSignal( tr_rwlock_t * rw )
    262 {
    263   if ( rw->wantToWrite )
    264     tr_condSignal( rw->writeCond );
    265   else if ( rw->wantToRead )
    266     tr_condBroadcast( rw->readCond );
    267 }
    268 
    269 tr_rwlock_t*
    270 tr_rwNew ( void )
    271 {
    272     tr_rwlock_t * rw = tr_new0( tr_rwlock_t, 1 );
    273     rw->lock = tr_lockNew( );
    274     rw->readCond = tr_condNew( );
    275     rw->writeCond = tr_condNew( );
    276     return rw;
    277 }
    278 
    279 void
    280 tr_rwReaderLock( tr_rwlock_t * rw )
    281 {
    282     tr_lockLock( rw->lock );
    283     rw->wantToRead++;
    284     while( rw->haveWriter || rw->wantToWrite )
    285         tr_condWait( rw->readCond, rw->lock );
    286     rw->wantToRead--;
    287     rw->readCount++;
    288     tr_lockUnlock( rw->lock );
    289 }
    290 
    291 int
    292 tr_rwReaderTrylock( tr_rwlock_t * rw )
    293 {
    294     int ret = FALSE;
    295     tr_lockLock( rw->lock );
    296     if ( !rw->haveWriter && !rw->wantToWrite ) {
    297         rw->readCount++;
    298         ret = TRUE;
    299     }
    300     tr_lockUnlock( rw->lock );
    301     return ret;
    302 
    303 }
    304 
    305 void
    306 tr_rwReaderUnlock( tr_rwlock_t * rw )
    307 {
    308     tr_lockLock( rw->lock );
    309     --rw->readCount;
    310     if( !rw->readCount )
    311         tr_rwSignal( rw );
    312     tr_lockUnlock( rw->lock );
    313 }
    314 
    315 void
    316 tr_rwWriterLock( tr_rwlock_t * rw )
    317 {
    318     tr_lockLock( rw->lock );
    319     rw->wantToWrite++;
    320     while( rw->haveWriter || rw->readCount )
    321         tr_condWait( rw->writeCond, rw->lock );
    322     rw->wantToWrite--;
    323     rw->haveWriter = TRUE;
    324     tr_lockUnlock( rw->lock );
    325 }
    326 
    327 int
    328 tr_rwWriterTrylock( tr_rwlock_t * rw )
    329 {
    330     int ret = FALSE;
    331     tr_lockLock( rw->lock );
    332     if( !rw->haveWriter && !rw->readCount )
    333         ret = rw->haveWriter = TRUE;
    334     tr_lockUnlock( rw->lock );
    335     return ret;
    336 }
    337 void
    338 tr_rwWriterUnlock( tr_rwlock_t * rw )
    339 {
    340     tr_lockLock( rw->lock );
    341     rw->haveWriter = FALSE;
    342     tr_rwSignal( rw );
    343     tr_lockUnlock( rw->lock );
    344 }
    345 
    346 void
    347 tr_rwFree( tr_rwlock_t * rw )
    348 {
    349     tr_condFree( rw->writeCond );
    350     tr_condFree( rw->readCond );
    351     tr_lockFree( rw->lock );
    352     tr_free( rw );
    353238}
    354239
     
    357242***/
    358243
    359 struct tr_cond_s
     244struct tr_cond
    360245{
    361246#ifdef __BEOS__
     
    365250#elif defined(WIN32)
    366251    tr_list * events;
    367     tr_lock_t * lock;
     252    tr_lock * lock;
    368253#else
    369254    pthread_cond_t cond;
     
    384269#endif
    385270
    386 tr_cond_t*
     271tr_cond*
    387272tr_condNew( void )
    388273{
    389     tr_cond_t * c = tr_new0( tr_cond_t, 1 );
     274    tr_cond * c = tr_new0( tr_cond, 1 );
    390275#ifdef __BEOS__
    391276    c->sem = create_sem( 1, "" );
     
    402287
    403288void
    404 tr_condWait( tr_cond_t * c, tr_lock_t * l )
     289tr_condWait( tr_cond * c, tr_lock * l )
    405290{
    406291#ifdef __BEOS__
     
    450335
    451336#ifdef __BEOS__
    452 static int condTrySignal( tr_cond_t * c )
     337static int condTrySignal( tr_cond * c )
    453338{
    454339    if( c->start == c->end )
     
    474359#endif
    475360void
    476 tr_condSignal( tr_cond_t * c )
     361tr_condSignal( tr_cond * c )
    477362{
    478363#ifdef __BEOS__
     
    497382
    498383void
    499 tr_condBroadcast( tr_cond_t * c )
     384tr_condBroadcast( tr_cond * c )
    500385{
    501386#ifdef __BEOS__
     
    521406
    522407void
    523 tr_condFree( tr_cond_t * c )
     408tr_condFree( tr_cond * c )
    524409{
    525410#ifdef __BEOS__
  • trunk/libtransmission/platform.h

    r2975 r3105  
    2525#define TR_PLATFORM_H
    2626
    27 typedef struct tr_lock_s   tr_lock_t;
    28 typedef struct tr_cond_s   tr_cond_t;
    29 typedef struct tr_thread_s tr_thread_t;
     27typedef struct tr_lock   tr_lock;
     28typedef struct tr_cond   tr_cond;
     29typedef struct tr_thread tr_thread;
    3030
    3131const char * tr_getHomeDirectory( void );
     
    3333const char * tr_getTorrentsDirectory( void );
    3434
    35 tr_thread_t*  tr_threadNew  ( void (*func)(void *), void * arg, const char * name );
    36 void          tr_threadJoin ( tr_thread_t * );
     35tr_thread*   tr_threadNew  ( void (*func)(void *), void * arg, const char * name );
     36void         tr_threadJoin ( tr_thread * );
     37int          tr_amInThread ( const tr_thread * );
    3738int           tr_amInThread ( const tr_thread_t * );
    3839
    39 tr_lock_t * tr_lockNew        ( void );
    40 void        tr_lockFree       ( tr_lock_t * );
    41 int         tr_lockTryLock    ( tr_lock_t * );
    42 void        tr_lockLock       ( tr_lock_t * );
    43 void        tr_lockUnlock     ( tr_lock_t * );
     40tr_lock *    tr_lockNew        ( void );
     41void         tr_lockFree       ( tr_lock * );
     42int          tr_lockTryLock    ( tr_lock * );
     43void         tr_lockLock       ( tr_lock * );
     44void         tr_lockUnlock     ( tr_lock * );
    4445
    45 tr_cond_t * tr_condNew       ( void );
    46 void        tr_condFree      ( tr_cond_t * );
    47 void        tr_condSignal    ( tr_cond_t * );
    48 void        tr_condBroadcast ( tr_cond_t * );
    49 void        tr_condWait      ( tr_cond_t *, tr_lock_t * );
    50 
    51 /***
    52 **** RW lock:
    53 **** The lock can be had by one writer or any number of readers.
    54 ***/
    55 
    56 typedef struct tr_rwlock_s tr_rwlock_t;
    57 
    58 tr_rwlock_t*  tr_rwNew           ( void );
    59 void          tr_rwFree          ( tr_rwlock_t * );
    60 void          tr_rwReaderLock    ( tr_rwlock_t * );
    61 int           tr_rwReaderTrylock ( tr_rwlock_t * );
    62 void          tr_rwReaderUnlock  ( tr_rwlock_t * );
    63 void          tr_rwWriterLock    ( tr_rwlock_t * );
    64 int           tr_rwWriterTrylock ( tr_rwlock_t * );
    65 void          tr_rwWriterUnlock  ( tr_rwlock_t * );
    66 
     46tr_cond *    tr_condNew       ( void );
     47void         tr_condFree      ( tr_cond * );
     48void         tr_condSignal    ( tr_cond * );
     49void         tr_condBroadcast ( tr_cond * );
     50void         tr_condWait      ( tr_cond *, tr_lock * );
    6751
    6852struct in_addr; /* forward declaration to calm gcc down */
  • trunk/libtransmission/ptrarray.c

    r2851 r3105  
    2020#define GROW 32
    2121
    22 struct tr_ptrArray_s
     22struct tr_ptrArray
    2323{
    2424    void ** items;
     
    2727};
    2828
    29 tr_ptrArray_t*
     29tr_ptrArray*
    3030tr_ptrArrayNew( void )
    3131{
    32     tr_ptrArray_t * p;
     32    tr_ptrArray * p;
    3333
    34     p = tr_new( tr_ptrArray_t, 1 );
     34    p = tr_new( tr_ptrArray, 1 );
    3535    p->n_items = 0;
    3636    p->n_alloc = GROW;
     
    4141
    4242void
    43 tr_ptrArrayFree( tr_ptrArray_t * t )
     43tr_ptrArrayFree( tr_ptrArray * t )
    4444{
    4545    assert( t != NULL );
     
    5151
    5252void**
    53 tr_ptrArrayPeek( tr_ptrArray_t * t, int * size )
     53tr_ptrArrayPeek( tr_ptrArray * t, int * size )
    5454{
    5555    *size = t->n_items;
     
    5757}
    5858
     59void*
     60tr_ptrArrayNth( tr_ptrArray* t, int i )
     61{
     62    assert( t != NULL  );
     63    assert( i >= 0 );
     64    assert( i < t->n_items );
     65
     66    return t->items[i];
     67}
     68
    5969int
    60 tr_ptrArraySize( const tr_ptrArray_t * t )
     70tr_ptrArraySize( const tr_ptrArray * t )
    6171{
    6272    return t->n_items;
     
    6474
    6575int
    66 tr_ptrArrayEmpty( const tr_ptrArray_t * t )
     76tr_ptrArrayEmpty( const tr_ptrArray * t )
    6777{
    6878    return t->n_items == 0;
     
    7080
    7181void
    72 tr_ptrArrayClear( tr_ptrArray_t * t )
     82tr_ptrArrayClear( tr_ptrArray * t )
    7383{
    7484    t->n_items = 0;
     
    7686
    7787int
    78 tr_ptrArrayInsert( tr_ptrArray_t * t, void * ptr, int pos )
     88tr_ptrArrayInsert( tr_ptrArray * t, void * ptr, int pos )
    7989{
    8090    if( pos<0 || pos>t->n_items )
     
    96106
    97107int
    98 tr_ptrArrayAppend( tr_ptrArray_t * t, void * ptr )
     108tr_ptrArrayAppend( tr_ptrArray * t, void * ptr )
    99109{
    100110    return tr_ptrArrayInsert( t, ptr, -1 );
     
    102112
    103113void
    104 tr_ptrArrayErase( tr_ptrArray_t * t, int begin, int end )
     114tr_ptrArrayErase( tr_ptrArray * t, int begin, int end )
    105115{
    106116    assert( begin >= 0 );
     
    121131
    122132int
    123 tr_ptrArrayLowerBound( const tr_ptrArray_t * t,
    124                        void                * ptr,
    125                        int                   compare( const void *,const void * ),
    126                        int                 * exact_match )
     133tr_ptrArrayLowerBound( const tr_ptrArray * t,
     134                       const void        * ptr,
     135                       int                 compare( const void *,const void * ),
     136                       int               * exact_match )
    127137{
    128     int c = -1;
    129138    int len = t->n_items;
    130139    int first = 0;
     
    134143        int half = len / 2;
    135144        int middle = first + half;
    136         c = compare( t->items[middle], ptr );
     145        const int c = compare( t->items[middle], ptr );
    137146        if( c < 0 ) {
    138147            first = middle + 1;
     
    155164
    156165int
    157 tr_ptrArrayInsertSorted( tr_ptrArray_t  * t,
    158                          void           * ptr,
    159                          int              compare(const void*,const void*) )
     166tr_ptrArrayInsertSorted( tr_ptrArray  * t,
     167                         void         * ptr,
     168                         int            compare(const void*,const void*) )
    160169{
    161170    const int pos = tr_ptrArrayLowerBound( t, ptr, compare, NULL );
     
    164173
    165174void*
    166 tr_ptrArrayFindSorted( tr_ptrArray_t  * t,
    167                        void           * ptr,
    168                        int              compare(const void*,const void*) )
     175tr_ptrArrayFindSorted( tr_ptrArray  * t,
     176                       const void   * ptr,
     177                       int            compare(const void*,const void*) )
    169178{
    170179    int match;
     
    174183
    175184void*
    176 tr_ptrArrayRemoveSorted( tr_ptrArray_t  * t,
    177                          void           * ptr,
    178                          int              compare(const void*,const void*) )
     185tr_ptrArrayRemoveSorted( tr_ptrArray  * t,
     186                         void         * ptr,
     187                         int            compare(const void*,const void*) )
    179188{
    180189    void * ret = NULL;
  • trunk/libtransmission/ptrarray.h

    r2849 r3105  
    1717 * A simple pointer array that resizes itself dynamically.
    1818 */
    19 typedef struct tr_ptrArray_s tr_ptrArray_t;
     19typedef struct tr_ptrArray tr_ptrArray;
    2020
    21 tr_ptrArray_t * tr_ptrArrayNew         ( void );
    22 void            tr_ptrArrayFree        ( tr_ptrArray_t* );
    23 void**          tr_ptrArrayPeek        ( tr_ptrArray_t*, int * size );
    24 void**          tr_ptrArrayBase        ( tr_ptrArray_t* );
    25 void            tr_ptrArrayClear       ( tr_ptrArray_t* );
    26 int             tr_ptrArrayInsert      ( tr_ptrArray_t*, void*, int pos );
    27 int             tr_ptrArrayAppend      ( tr_ptrArray_t*, void* );
    28 void            tr_ptrArrayErase       ( tr_ptrArray_t*, int begin, int end );
    29 int             tr_ptrArraySize        ( const tr_ptrArray_t* );
    30 int             tr_ptrArrayEmpty       ( const tr_ptrArray_t* );
     21tr_ptrArray * tr_ptrArrayNew     ( void );
    3122
    32 int             tr_ptrArrayInsertSorted( tr_ptrArray_t*, void*,
    33                                          int compare(const void*,const void*) );
    34 void*           tr_ptrArrayRemoveSorted( tr_ptrArray_t*, void*,
    35                                          int compare(const void*,const void*) );
    36 void*           tr_ptrArrayFindSorted  ( tr_ptrArray_t*, void*,
    37                                          int compare(const void*,const void*) );
     23void    tr_ptrArrayFree          ( tr_ptrArray* );
     24void*   tr_ptrArrayNth           ( tr_ptrArray*, int n );
     25void**  tr_ptrArrayPeek          ( tr_ptrArray*, int * size );
     26void**  tr_ptrArrayBase          ( tr_ptrArray* );
     27void    tr_ptrArrayClear         ( tr_ptrArray* );
     28int     tr_ptrArrayInsert        ( tr_ptrArray*, void*, int pos );
     29int     tr_ptrArrayAppend        ( tr_ptrArray*, void* );
     30void    tr_ptrArrayErase         ( tr_ptrArray*, int begin, int end );
     31int     tr_ptrArraySize          ( const tr_ptrArray* );
     32int     tr_ptrArrayEmpty         ( const tr_ptrArray* );
     33int     tr_ptrArrayInsertSorted  ( tr_ptrArray*, void*,
     34                                   int compare(const void*,const void*) );
     35void*   tr_ptrArrayRemoveSorted  ( tr_ptrArray*, void*,
     36                                   int compare(const void*,const void*) );
     37void*   tr_ptrArrayFindSorted    ( tr_ptrArray*, const void*,
     38                                   int compare(const void*,const void*) );
    3839
    3940#endif
  • trunk/libtransmission/publish.c

    r2851 r3105  
    1111 */
    1212
     13#include <assert.h>
    1314#include "list.h"
    1415#include "publish.h"
     
    2324struct tr_publisher_s
    2425{
    25     tr_list_t * list;
     26    tr_list * list;
    2627};
    2728
     
    3334
    3435void
    35 tr_publisherFree( tr_publisher_t * p )
     36tr_publisherFree( tr_publisher_t ** p )
    3637{
    37     tr_list_free( &p->list );
    38     tr_free( p );
     38    assert( p != NULL );
     39    assert( *p != NULL );
     40
     41    tr_list_free( &(*p)->list );
     42    tr_free( *p );
     43    *p = NULL;
    3944}
    4045
     
    6469                     void            * event )
    6570{
    66     tr_list_t * walk;
     71    tr_list * walk;
    6772    for( walk=p->list; walk!=NULL; )
    6873    {
    69         tr_list_t * next = walk->next;
     74        tr_list * next = walk->next;
    7075        struct tr_publisher_node * node = (struct tr_publisher_node*)walk->data;
    7176        (node->func)(source, event, node->user_data);
  • trunk/libtransmission/publish.h

    r2849 r3105  
    4343tr_publisher_t *   tr_publisherNew         ( void );
    4444
    45 void               tr_publisherFree        ( tr_publisher_t    * publisher );
     45void               tr_publisherFree        ( tr_publisher_t   ** publisher );
    4646
    4747void               tr_publisherPublish     ( tr_publisher_t    * publisher,
  • trunk/libtransmission/ratecontrol.c

    r2590 r3105  
    3939{
    4040    uint64_t date;
    41     int      size;
     41    uint64_t size;
    4242}
    4343tr_transfer_t;
    4444
    45 struct tr_ratecontrol_s
     45struct tr_ratecontrol
    4646{
    47     tr_lock_t * lock;
     47    tr_lock * lock;
    4848    int limit;
    4949    int newest;
     
    5353/* return the xfer rate over the last `interval' seconds in KiB/sec */
    5454static float
    55 rateForInterval( const tr_ratecontrol_t * r, int interval_msec )
     55rateForInterval( const tr_ratecontrol * r, int interval_msec )
    5656{
    5757    uint64_t bytes = 0;
    58     const uint64_t now = tr_date ();
     58    const uint64_t cutoff = tr_date () - interval_msec;
    5959    int i = r->newest;
    6060    for( ;; )
    6161    {
    62         if( r->transfers[i].date + interval_msec < now )
     62        if( r->transfers[i].date < cutoff )
    6363            break;
    6464
     
    7676***/
    7777
    78 tr_ratecontrol_t*
     78tr_ratecontrol*
    7979tr_rcInit( void )
    8080{
    81     tr_ratecontrol_t * r = tr_new0( tr_ratecontrol_t, 1 );
     81    tr_ratecontrol * r = tr_new0( tr_ratecontrol, 1 );
    8282    r->limit = 0;
    8383    r->lock = tr_lockNew( );
     
    8686
    8787void
    88 tr_rcClose( tr_ratecontrol_t * r )
     88tr_rcClose( tr_ratecontrol * r )
    8989{
    9090    tr_rcReset( r );
     
    9898
    9999int
    100 tr_rcCanTransfer( const tr_ratecontrol_t * r )
     100tr_rcCanTransfer( const tr_ratecontrol * r )
    101101{
    102102    int ret;
    103     tr_lockLock( (tr_lock_t*)r->lock );
    104103
    105     ret = rateForInterval( r, SHORT_INTERVAL_MSEC ) < r->limit;
     104    if( r == NULL )
     105        ret = 0;
     106    else {
     107        tr_lockLock( (tr_lock*)r->lock );
     108        ret = rateForInterval( r, SHORT_INTERVAL_MSEC ) < r->limit;
     109        tr_lockUnlock( (tr_lock*)r->lock );
     110    }
    106111
    107     tr_lockUnlock( (tr_lock_t*)r->lock );
    108112    return ret;
    109113}
    110114
    111115float
    112 tr_rcRate( const tr_ratecontrol_t * r )
     116tr_rcRate( const tr_ratecontrol * r )
    113117{
    114118    float ret;
    115     tr_lockLock( (tr_lock_t*)r->lock );
    116119
    117     ret = rateForInterval( r, LONG_INTERVAL_MSEC );
     120    if( r == NULL )
     121        ret = 0.0f;
     122    else {
     123        tr_lockLock( (tr_lock*)r->lock );
     124        ret = rateForInterval( r, LONG_INTERVAL_MSEC );
     125        tr_lockUnlock( (tr_lock*)r->lock );
     126    }
    118127
    119     tr_lockUnlock( (tr_lock_t*)r->lock );
    120128    return ret;
    121129}
     
    126134
    127135void
    128 tr_rcTransferred( tr_ratecontrol_t * r, int size )
     136tr_rcTransferred( tr_ratecontrol * r, size_t size )
    129137{
    130138    uint64_t now;
     
    133141        return;
    134142   
    135     tr_lockLock( (tr_lock_t*)r->lock );
     143    tr_lockLock( (tr_lock*)r->lock );
    136144
    137145    now = tr_date ();
     
    144152    }
    145153
    146     tr_lockUnlock( (tr_lock_t*)r->lock );
     154    tr_lockUnlock( (tr_lock*)r->lock );
    147155}
    148156
    149157void
    150 tr_rcReset( tr_ratecontrol_t * r )
     158tr_rcReset( tr_ratecontrol * r )
    151159{
    152     tr_lockLock( (tr_lock_t*)r->lock );
     160    tr_lockLock( (tr_lock*)r->lock );
    153161    r->newest = 0;
    154162    memset( r->transfers, 0, sizeof(tr_transfer_t) * HISTORY_SIZE );
    155     tr_lockUnlock( (tr_lock_t*)r->lock );
     163    tr_lockUnlock( (tr_lock*)r->lock );
    156164}
    157165
    158166void
    159 tr_rcSetLimit( tr_ratecontrol_t * r, int limit )
     167tr_rcSetLimit( tr_ratecontrol * r, int limit )
    160168{
    161     tr_lockLock( (tr_lock_t*)r->lock );
     169    tr_lockLock( (tr_lock*)r->lock );
    162170    r->limit = limit;
    163     tr_lockUnlock( (tr_lock_t*)r->lock );
     171    tr_lockUnlock( (tr_lock*)r->lock );
    164172}
    165173
    166174int
    167 tr_rcGetLimit( const tr_ratecontrol_t * r )
     175tr_rcGetLimit( const tr_ratecontrol * r )
    168176{
    169177    return r->limit;
  • trunk/libtransmission/ratecontrol.h

    r2388 r3105  
    2626#define _TR_RATECONTROL_H_
    2727
    28 typedef struct tr_ratecontrol_s tr_ratecontrol_t;
     28typedef struct tr_ratecontrol tr_ratecontrol;
    2929
    30 tr_ratecontrol_t * tr_rcInit( void );
    31 void               tr_rcSetLimit( tr_ratecontrol_t *, int );
    32 int                tr_rcGetLimit( const tr_ratecontrol_t * );
    33 int                tr_rcCanTransfer( const tr_ratecontrol_t * );
    34 void               tr_rcTransferred( tr_ratecontrol_t *, int );
    35 float              tr_rcRate( const tr_ratecontrol_t * );
    36 void               tr_rcReset( tr_ratecontrol_t * );
    37 void               tr_rcClose( tr_ratecontrol_t * );
     30tr_ratecontrol * tr_rcInit( void );
     31void             tr_rcSetLimit( tr_ratecontrol *, int );
     32int              tr_rcGetLimit( const tr_ratecontrol * );
     33int              tr_rcCanTransfer( const tr_ratecontrol * );
     34void             tr_rcTransferred( tr_ratecontrol *, size_t byteCount );
     35float            tr_rcRate( const tr_ratecontrol * );
     36void             tr_rcReset( tr_ratecontrol * );
     37void             tr_rcClose( tr_ratecontrol * );
    3838
    3939#endif
  • trunk/libtransmission/shared.c

    r2805 r3105  
    2626#include <stdlib.h>
    2727#include <string.h>
     28#include <stdio.h>
    2829
    2930#include <sys/types.h>
    3031
    3132#include "transmission.h"
    32 #include "choking.h"
     33#include "handshake.h"
    3334#include "natpmp.h"
    3435#include "net.h"
    35 #include "peer.h"
     36#include "peer-io.h"
     37#include "peer-mgr.h"
    3638#include "platform.h"
    3739#include "shared.h"
     40#include "trevent.h"
    3841#include "upnp.h"
    3942#include "utils.h"
    4043
    41 /* Maximum number of peers that we keep in our local list */
    42 /* This is an arbitrary number, but it seems to work well */
    43 #define MAX_PEER_COUNT 128
    44 
    45 struct tr_shared_s
    46 {
    47     tr_handle_t  * h;
    48     volatile int   die;
    49     tr_thread_t  * thread;
    50     tr_lock_t    * lock;
     44struct tr_shared
     45{
     46    tr_handle    * h;
     47    tr_lock      * lock;
     48    tr_timer     * pulseTimer;
    5149
    5250    /* Incoming connections */
    53     int          publicPort;
    54     int          bindPort;
    55     int          bindSocket;
    56     int          peerCount;
    57     tr_peer_t    * peers[MAX_PEER_COUNT];
     51    int publicPort;
     52    int bindPort;
     53    int bindSocket;
    5854
    5955    /* NAT-PMP/UPnP */
    6056    tr_natpmp_t  * natpmp;
    6157    tr_upnp_t    * upnp;
    62 
    63     /* Choking */
    64     tr_choking_t * choking;
    6558};
    6659
     
    6861 * Local prototypes
    6962 **********************************************************************/
    70 static void SharedLoop( void * );
    71 static void SetPublicPort( tr_shared_t *, int );
    72 static void AcceptPeers( tr_shared_t * );
    73 static void ReadPeers( tr_shared_t * );
    74 static void DispatchPeers( tr_shared_t * );
     63static int SharedLoop( void * );
     64static void SetPublicPort( tr_shared *, int );
     65static void AcceptPeers( tr_shared * );
    7566
    7667
     
    8071 *
    8172 **********************************************************************/
    82 tr_shared_t * tr_sharedInit( tr_handle_t * h )
    83 {
    84     tr_shared_t * s = calloc( 1, sizeof( tr_shared_t ) );
     73tr_shared * tr_sharedInit( tr_handle * h )
     74{
     75    tr_shared * s = calloc( 1, sizeof( tr_shared ) );
    8576
    8677    s->h          = h;
     
    9182    s->natpmp     = tr_natpmpInit();
    9283    s->upnp       = tr_upnpInit();
    93     s->choking    = tr_chokingInit( h );
    94     s->die        = 0;
    95     s->thread     = tr_threadNew( SharedLoop, s, "shared" );
     84    s->pulseTimer   = tr_timerNew( h, SharedLoop, s, 250 );
    9685
    9786    return s;
     
    10392 *
    10493 **********************************************************************/
    105 void tr_sharedClose( tr_shared_t * s )
    106 {
    107     int ii;
    108 
    109     /* Stop the thread */
    110     s->die = 1;
    111     tr_threadJoin( s->thread );
    112 
    113     /* Clean up */
    114     for( ii = 0; ii < s->peerCount; ii++ )
    115     {
    116         tr_peerDestroy( s->peers[ii] );
    117     }
    118     if( s->bindSocket > -1 )
    119     {
    120         tr_netClose( s->bindSocket );
    121     }
     94void tr_sharedClose( tr_shared * s )
     95{
     96fprintf( stderr, "deleting pulse tag\n" );
     97    tr_timerFree( &s->pulseTimer );
     98
     99    tr_netClose( s->bindSocket );
    122100    tr_lockFree( s->lock );
    123101    tr_natpmpClose( s->natpmp );
    124102    tr_upnpClose( s->upnp );
    125     tr_chokingClose( s->choking );
    126103    free( s );
    127104}
    128105
    129 /***********************************************************************
    130  * tr_sharedLock, tr_sharedUnlock
    131  ***********************************************************************
    132  *
    133  **********************************************************************/
    134 void tr_sharedLock( tr_shared_t * s )
     106/**
     107***
     108**/
     109
     110void tr_sharedLock( tr_shared * s )
    135111{
    136112    tr_lockLock( s->lock );
    137113}
    138 void tr_sharedUnlock( tr_shared_t * s )
     114void tr_sharedUnlock( tr_shared * s )
    139115{
    140116    tr_lockUnlock( s->lock );
     
    146122 *
    147123 **********************************************************************/
    148 void tr_sharedSetPort( tr_shared_t * s, int port )
     124void tr_sharedSetPort( tr_shared * s, int port )
    149125{
    150126#ifdef BEOS_NETSERVER
     
    197173}
    198174
    199 /***********************************************************************
    200  * tr_sharedGetPublicPort
    201  ***********************************************************************
    202  *
    203  **********************************************************************/
    204 int tr_sharedGetPublicPort( tr_shared_t * s )
     175int tr_sharedGetPublicPort( tr_shared * s )
    205176{
    206177    return s->publicPort;
     
    212183 *
    213184 **********************************************************************/
    214 void tr_sharedTraversalEnable( tr_shared_t * s, int enable )
     185void tr_sharedTraversalEnable( tr_shared * s, int enable )
    215186{
    216187    if( enable )
     
    226197}
    227198
    228 int tr_sharedTraversalStatus( tr_shared_t * s )
     199int tr_sharedTraversalStatus( tr_shared * s )
    229200{
    230201    int statuses[] = {
     
    256227}
    257228
    258 /***********************************************************************
    259  * tr_sharedSetLimit
    260  **********************************************************************/
    261 void tr_sharedSetLimit( tr_shared_t * s, int limit )
    262 {
    263     tr_chokingSetLimit( s->choking, limit );
    264 }
    265 
    266229
    267230/***********************************************************************
     
    272235 * SharedLoop
    273236 **********************************************************************/
    274 static void SharedLoop( void * _s )
    275 {
    276     tr_shared_t * s = _s;
    277     uint64_t      date1, date2, lastchoke = 0;
    278     int           newPort;
     237static int
     238SharedLoop( void * vs )
     239{
     240    int newPort;
     241    tr_shared * s = vs;
    279242
    280243    tr_sharedLock( s );
    281244
    282     while( !s->die )
    283     {
    284         date1 = tr_date();
    285 
    286         /* NAT-PMP and UPnP pulses */
    287         newPort = -1;
    288         tr_natpmpPulse( s->natpmp, &newPort );
    289         if( 0 < newPort && newPort != s->publicPort )
    290         {
    291             SetPublicPort( s, newPort );
    292         }
    293         tr_upnpPulse( s->upnp );
    294 
    295         /* Handle incoming connections */
    296         AcceptPeers( s );
    297         ReadPeers( s );
    298         DispatchPeers( s );
    299 
    300         /* Update choking every second */
    301         if( date1 > lastchoke + 1000 )
    302         {
    303             tr_chokingPulse( s->choking );
    304             lastchoke = date1;
    305         }
    306 
    307         tr_swiftPulse ( s->h );
    308 
    309         /* Wait up to 20 ms */
    310         date2 = tr_date();
    311         if( date2 < date1 + 20 )
    312         {
    313             tr_sharedUnlock( s );
    314             tr_wait( date1 + 20 - date2 );
    315             tr_sharedLock( s );
    316         }
    317     }
     245    /* NAT-PMP and UPnP pulses */
     246    newPort = -1;
     247    tr_natpmpPulse( s->natpmp, &newPort );
     248    if( 0 < newPort && newPort != s->publicPort )
     249        SetPublicPort( s, newPort );
     250    tr_upnpPulse( s->upnp );
     251
     252    /* Handle incoming connections */
     253    AcceptPeers( s );
    318254
    319255    tr_sharedUnlock( s );
     256
     257    return TRUE;
    320258}
    321259
     
    323261 * SetPublicPort
    324262 **********************************************************************/
    325 static void SetPublicPort( tr_shared_t * s, int port )
    326 {
    327     tr_handle_t * h = s->h;
    328     tr_torrent_t * tor;
     263static void SetPublicPort( tr_shared * s, int port )
     264{
     265    tr_handle * h = s->h;
     266    tr_torrent * tor;
    329267
    330268    s->publicPort = port;
     
    339277 * Check incoming connections and add the peers to our local list
    340278 **********************************************************************/
    341 static void AcceptPeers( tr_shared_t * s )
    342 {
    343     int socket;
    344     struct in_addr addr;
    345 
     279
     280static void
     281AcceptPeers( tr_shared * s )
     282{
    346283    for( ;; )
    347284    {
    348         if( s->bindSocket < 0 || s->peerCount >= MAX_PEER_COUNT )
    349         {
     285        int socket;
     286        struct in_addr addr;
     287
     288        if( s->bindSocket < 0 || !tr_peerMgrIsAcceptingConnections( s->h->peerMgr ) )
    350289            break;
    351         }
    352290
    353291        socket = tr_netAccept( s->bindSocket, &addr, NULL );
    354292        if( socket < 0 )
    355         {
    356293            break;
    357         }
    358         s->peers[s->peerCount++] = tr_peerInit( &addr, 0, socket,
    359                                                 TR_PEER_FROM_INCOMING );
    360     }
    361 }
    362 
    363 /***********************************************************************
    364  * ReadPeers
    365  ***********************************************************************
    366  * Try to read handshakes
    367  **********************************************************************/
    368 static void ReadPeers( tr_shared_t * s )
    369 {
    370     int ii;
    371 
    372     for( ii = 0; ii < s->peerCount; )
    373     {
    374         if( tr_peerRead( s->peers[ii] ) )
    375         {
    376             tr_peerDestroy( s->peers[ii] );
    377             s->peerCount--;
    378             memmove( &s->peers[ii], &s->peers[ii+1],
    379                      ( s->peerCount - ii ) * sizeof( tr_peer_t * ) );
    380             continue;
    381         }
    382         ii++;
    383     }
    384 }
    385 
    386 /***********************************************************************
    387  * DispatchPeers
    388  ***********************************************************************
    389  * If we got a handshake, try to find the torrent for this peer
    390  **********************************************************************/
    391 static void DispatchPeers( tr_shared_t * s )
    392 {
    393     tr_handle_t * h = s->h;
    394     int ii;
    395     const uint64_t now = tr_date();
    396 
    397     for( ii = 0; ii < s->peerCount; )
    398     {
    399         const uint8_t * hash = tr_peerHash( s->peers[ii] );
    400 
    401         if( !hash && now > tr_peerDate( s->peers[ii] ) + 10000 )
    402         {
    403             /* 10 seconds and no handshake, drop it */
    404             tr_peerDestroy( s->peers[ii] );
    405             goto removePeer;
    406         }
    407         if( hash )
    408         {
    409             tr_torrent_t * tor;
    410 
    411             for( tor = h->torrentList; tor; tor = tor->next )
    412             {
    413                 tr_torrentWriterLock( tor );
    414                 if( tor->runStatus != TR_RUN_RUNNING )
    415                 {
    416                     tr_torrentWriterUnlock( tor );
    417                     continue;
    418                 }
    419 
    420                 if( !memcmp( tor->info.hash, hash, SHA_DIGEST_LENGTH ) )
    421                 {
    422                     /* Found it! */
    423                     tr_torrentAttachPeer( tor, s->peers[ii] );
    424                     tr_torrentWriterUnlock( tor );
    425                     goto removePeer;
    426                 }
    427                 tr_torrentWriterUnlock( tor );
    428             }
    429 
    430             /* Couldn't find a torrent, we probably removed it */
    431             tr_peerDestroy( s->peers[ii] );
    432             goto removePeer;
    433         }
    434         ii++;
    435         continue;
    436 
    437 removePeer:
    438         s->peerCount--;
    439         memmove( &s->peers[ii], &s->peers[ii+1],
    440                 ( s->peerCount - ii ) * sizeof( tr_peer_t * ) );
    441     }
    442 }
    443 
     294
     295        tr_peerMgrAddIncoming( s->h->peerMgr, &addr, socket );
     296    }
     297}
  • trunk/libtransmission/shared.h

    r2555 r3105  
    2828#include "transmission.h"
    2929
    30 typedef struct tr_shared_s tr_shared_t;
     30typedef struct tr_shared tr_shared;
    3131
    3232/***********************************************************************
     
    3636 * among the torrents: NAT-PMP/UPnP, incoming connections, peer choking
    3737 **********************************************************************/
    38 tr_shared_t * tr_sharedInit           ( tr_handle_t * );
    39 void          tr_sharedClose          ( tr_shared_t * );
     38tr_shared * tr_sharedInit           ( tr_handle * );
     39void        tr_sharedClose          ( tr_shared * );
    4040
    4141/***********************************************************************
     
    4545 * thread
    4646 **********************************************************************/
    47 void          tr_sharedLock           ( tr_shared_t * );
    48 void          tr_sharedUnlock         ( tr_shared_t * );
     47void          tr_sharedLock           ( tr_shared * );
     48void          tr_sharedUnlock         ( tr_shared * );
    4949
    5050/***********************************************************************
     
    5454 * should be called with the shared lock held.
    5555 **********************************************************************/
    56 void         tr_sharedSetPort         ( tr_shared_t *, int port );
    57 int          tr_sharedGetPublicPort   ( tr_shared_t * s );
     56void         tr_sharedSetPort         ( tr_shared *, int port );
     57int          tr_sharedGetPublicPort   ( tr_shared * s );
    5858
    5959/***********************************************************************
     
    6363 * be called with the shared lock held.
    6464 **********************************************************************/
    65 void         tr_sharedTraversalEnable ( tr_shared_t *, int enable );
    66 int          tr_sharedTraversalStatus ( tr_shared_t * );
     65void         tr_sharedTraversalEnable ( tr_shared *, int enable );
     66int          tr_sharedTraversalStatus ( tr_shared * );
    6767
    68 /***********************************************************************
    69  * tr_sharedSetLimit
    70  ***********************************************************************
    71  *
    72  **********************************************************************/
    73 void         tr_sharedSetLimit        ( tr_shared_t *, int limit );
    7468
    7569#endif
  • trunk/libtransmission/torrent.c

    r2891 r3105  
    3232#include "transmission.h"
    3333#include "completion.h"
     34#include "crypto.h" /* for tr_sha1 */
    3435#include "fastresume.h"
     36#include "handshake.h"
    3537#include "inout.h"
    3638#include "metainfo.h"
    3739#include "net.h" /* tr_netNtop */
    3840#include "peer.h"
     41#include "peer-mgr.h"
    3942#include "platform.h"
    4043#include "ratecontrol.h"
     
    4245#include "tracker.h"
    4346#include "trcompat.h" /* for strlcpy */
     47#include "trevent.h"
    4448#include "utils.h"
     49
     50/***
     51****
     52***/
     53
     54int
     55tr_torrentExists( tr_handle       * handle,
     56                  const uint8_t   * torrentHash )
     57{
     58    return tr_torrentFindFromHash( handle, torrentHash ) != NULL;
     59}
     60
     61tr_torrent*
     62tr_torrentFindFromHash( tr_handle      * handle,
     63                        const uint8_t  * torrentHash )
     64{
     65    tr_torrent * tor;
     66
     67    for( tor = handle->torrentList; tor; tor = tor->next )
     68        if( !memcmp( tor->info.hash, torrentHash, SHA_DIGEST_LENGTH ) )
     69            return tor;
     70
     71    return NULL;
     72}
     73
     74tr_torrent*
     75tr_torrentFindFromObfuscatedHash( tr_handle      * handle,
     76                                  const uint8_t  * obfuscatedTorrentHash )
     77{
     78    tr_torrent * tor;
     79
     80    for( tor = handle->torrentList; tor; tor = tor->next )
     81        if( !memcmp( tor->obfuscatedHash, obfuscatedTorrentHash, SHA_DIGEST_LENGTH ) )
     82            return tor;
     83
     84    return NULL;
     85}
    4586
    4687/***
     
    4990
    5091void
    51 tr_torrentReaderLock( const tr_torrent_t * tor )
    52 {
    53     tr_rwReaderLock ( (tr_rwlock_t*)tor->lock );
    54 }
    55 
    56 void
    57 tr_torrentReaderUnlock( const tr_torrent_t * tor )
    58 {
    59     tr_rwReaderUnlock ( (tr_rwlock_t*)tor->lock );
    60 }
    61 
    62 void
    63 tr_torrentWriterLock( tr_torrent_t * tor )
    64 {
    65     tr_rwWriterLock ( tor->lock );
    66 }
    67 
    68 void
    69 tr_torrentWriterUnlock( tr_torrent_t * tor )
    70 {
    71     tr_rwWriterUnlock ( tor->lock );
     92tr_torrentLock( const tr_torrent * tor )
     93{
     94    tr_lockLock ( (tr_lock*)tor->lock );
     95}
     96
     97void
     98tr_torrentUnlock( const tr_torrent * tor )
     99{
     100    tr_lockUnlock ( (tr_lock*)tor->lock );
    72101}
    73102
     
    77106
    78107void
    79 tr_torrentSetSpeedMode( tr_torrent_t     * tor,
    80                         int                up_or_down,
    81                         tr_speedlimit_t    mode )
    82 {
    83     tr_speedlimit_t * limit = up_or_down==TR_UP
     108tr_torrentSetSpeedMode( tr_torrent   * tor,
     109                        int            up_or_down,
     110                        tr_speedlimit  mode )
     111{
     112    tr_speedlimit * limit = up_or_down==TR_UP
    84113        ? &tor->uploadLimitMode
    85114        : &tor->downloadLimitMode;
     
    87116}
    88117
    89 tr_speedlimit_t
    90 tr_torrentGetSpeedMode( const tr_torrent_t * tor,
    91                         int                  up_or_down)
     118tr_speedlimit
     119tr_torrentGetSpeedMode( const tr_torrent * tor,
     120                        int                up_or_down)
    92121{
    93122    return up_or_down==TR_UP ? tor->uploadLimitMode
     
    96125
    97126void
    98 tr_torrentSetSpeedLimit( tr_torrent_t   * tor,
    99                          int              up_or_down,
    100                          int              single_KiB_sec )
    101 {
    102     tr_ratecontrol_t * rc = up_or_down==TR_UP ? tor->upload : tor->download;
     127tr_torrentSetSpeedLimit( tr_torrent   * tor,
     128                         int            up_or_down,
     129                         int            single_KiB_sec )
     130{
     131    tr_ratecontrol * rc = up_or_down==TR_UP ? tor->upload : tor->download;
    103132    tr_rcSetLimit( rc, single_KiB_sec );
    104133}
    105134
    106135int
    107 tr_torrentGetSpeedLimit( const tr_torrent_t  * tor,
    108                          int                   up_or_down )
    109 {
    110     tr_ratecontrol_t * rc = up_or_down==TR_UP ? tor->upload : tor->download;
     136tr_torrentGetSpeedLimit( const tr_torrent  * tor,
     137                         int                 up_or_down )
     138{
     139    tr_ratecontrol * rc = up_or_down==TR_UP ? tor->upload : tor->download;
    111140    return tr_rcGetLimit( rc );
    112141}
     
    116145***/
    117146
    118 static void setRunState( tr_torrent_t *, run_status_t );
    119 
    120147static void
    121148onTrackerResponse( void * tracker UNUSED, void * vevent, void * user_data )
    122149{
    123     tr_torrent_t * tor = (tr_torrent_t *) user_data;
     150    tr_torrent * tor = (tr_torrent *) user_data;
    124151    tr_tracker_event_t * event = (tr_tracker_event_t *) vevent;
    125152
     
    127154    {
    128155        case TR_TRACKER_PEERS:
    129             tr_torrentAddCompact( tor, TR_PEER_FROM_TRACKER,
    130                                   event->peerCompact, event->peerCount );
     156            tr_peerMgrAddPeers( tor->handle->peerMgr,
     157                                tor->info.hash,
     158                                TR_PEER_FROM_TRACKER,
     159                                event->peerCompact,
     160                                event->peerCount );
    131161            break;
    132162
     
    144174
    145175        case TR_TRACKER_STOPPED:
    146             if( tor->runStatus == TR_RUN_STOPPING_NET_WAIT )
    147                 setRunState( tor, TR_RUN_STOPPED );
     176            //assert( tor->runStatus == TR_RUN_STOPPING );
     177            tor->runStatus = TR_RUN_STOPPED;
    148178            break;
    149179    }
     
    157187
    158188static int
    159 getBytePiece( const tr_info_t * info, uint64_t byteOffset )
     189getBytePiece( const tr_info * info, uint64_t byteOffset )
    160190{
    161191    assert( info != NULL );
     
    166196
    167197static void
    168 initFilePieces ( tr_info_t * info, int fileIndex )
    169 {
    170     tr_file_t * file = &info->files[fileIndex];
     198initFilePieces ( tr_info * info, int fileIndex )
     199{
     200    tr_file * file = &info->files[fileIndex];
    171201    uint64_t firstByte, lastByte;
    172202
     
    182212
    183213static tr_priority_t
    184 calculatePiecePriority ( const tr_torrent_t * tor,
    185                          int                  piece )
     214calculatePiecePriority ( const tr_torrent * tor,
     215                         int                piece )
    186216{
    187217    int i;
     
    190220    for( i=0; i<tor->info.fileCount; ++i )
    191221    {
    192         const tr_file_t * file = &tor->info.files[i];
     222        const tr_file * file = &tor->info.files[i];
    193223        if ( file->firstPiece <= piece
    194224          && file->lastPiece  >= piece
     
    208238
    209239static void
    210 tr_torrentInitFilePieces( tr_torrent_t * tor )
     240tr_torrentInitFilePieces( tr_torrent * tor )
    211241{
    212242    int i;
     
    225255}
    226256
    227 static void torrentThreadLoop( void * );
     257static void recheckCpState( tr_torrent * );
    228258
    229259static void
    230 torrentRealInit( tr_handle_t   * h,
    231                  tr_torrent_t  * tor,
    232                  const char    * destination,
    233                  int             flags )
     260tr_torrentStartImpl( tr_torrent * tor )
     261{
     262    assert( tor != NULL );
     263    assert( tor->runStatus == TR_RUN_RUNNING );
     264
     265    *tor->errorString = '\0';
     266    tr_torrentResetTransferStats( tor );
     267    recheckCpState( tor );
     268    tor->startDate = tr_date();
     269    tr_trackerStart( tor->tracker );
     270    tr_peerMgrStartTorrent( tor->handle->peerMgr, tor->info.hash );
     271}
     272
     273static void
     274recheckDoneCB( tr_torrent * tor )
     275{
     276    recheckCpState( tor );
     277
     278    if( tor->runStatus == TR_RUN_RUNNING )
     279        tr_torrentStartImpl( tor );
     280}
     281
     282static void
     283torrentRealInit( tr_handle_t * h,
     284                 tr_torrent  * tor,
     285                 const char  * destination,
     286                 int           flags )
    234287{
    235288    uint64_t loaded;
    236289    uint64_t t;
    237     char name[512];
    238     tr_bitfield_t * uncheckedPieces;
    239     tr_info_t * info = &tor->info;
     290    tr_bitfield * uncheckedPieces;
     291    tr_info * info = &tor->info;
    240292   
    241293    tor->info.flags |= flags;
     
    299351    tr_torrentInitFilePieces( tor );
    300352
    301     tor->lock = tr_rwNew( );
     353    tor->lock = tr_lockNew( );
    302354
    303355    tor->upload         = tr_rcInit();
    304356    tor->download       = tr_rcInit();
    305357    tor->swarmspeed     = tr_rcInit();
     358
     359    tr_sha1( tor->obfuscatedHash, "req2", 4,
     360                                  info->hash, SHA_DIGEST_LENGTH,
     361                                  NULL );
    306362 
    307363    /* We have a new torrent */
     
    309365
    310366    tr_sharedUnlock( h->shared );
     367
     368    tr_peerMgrAddTorrent( h->peerMgr, tor );
    311369
    312370    if( !h->isPortSet )
     
    347405    tor->tracker = tr_trackerNew( tor );
    348406    tor->trackerSubscription = tr_trackerSubscribe( tor->tracker, onTrackerResponse, tor );
    349     if( tor->runStatus == TR_RUN_RUNNING )
    350         tr_trackerStart( tor->tracker );
    351407
    352408    tr_sharedLock( h->shared );
     
    356412    tr_sharedUnlock( h->shared );
    357413
    358     snprintf( name, sizeof( name ), "torrent %p (%s)", tor, tor->info.name );
    359     tor->thread = tr_threadNew( torrentThreadLoop, tor, name );
     414    tr_ioRecheckAdd( tor, recheckDoneCB, tor->runStatus );
    360415}
    361416
     
    365420              const char          * name )
    366421{
    367     const tr_torrent_t * tor;
     422    const tr_torrent * tor;
    368423   
    369424    for( tor=h->torrentList; tor; tor=tor->next )
     
    379434            const uint8_t       * hash )
    380435{
    381     const tr_torrent_t * tor;
     436    const tr_torrent * tor;
    382437
    383438    for( tor=h->torrentList; tor; tor=tor->next )
     
    391446infoCanAdd( const tr_handle_t   * h,
    392447            const char          * destination,
    393             const tr_info_t     * info )
     448            const tr_info     * info )
    394449{
    395450    if( hashExists( h, info->hash ) )
     
    406461                 const char         * path,
    407462                 const char         * destination,
    408                  tr_info_t          * setme_info )
     463                 tr_info          * setme_info )
    409464{
    410465    int ret, doFree;
    411     tr_info_t tmp;
     466    tr_info tmp;
    412467
    413468    if( setme_info == NULL )
    414469        setme_info = &tmp;
    415470
    416     memset( setme_info, 0, sizeof( tr_info_t ) );
     471    memset( setme_info, 0, sizeof( tr_info ) );
    417472    ret = tr_metainfoParseFile( setme_info, h->tag, path, FALSE );
    418473    doFree = !ret && (setme_info == &tmp);
     
    427482}
    428483 
    429 tr_torrent_t *
     484tr_torrent *
    430485tr_torrentInit( tr_handle_t   * h,
    431486                const char    * path,
     
    436491    int val;
    437492    int tmpError;
    438     tr_torrent_t * tor = NULL;
     493    tr_torrent * tor = NULL;
    439494
    440495    if( !error )
     
    443498    if(( val = tr_torrentParse( h, path, destination, NULL )))
    444499        *error = val;
    445     else if(!(( tor = tr_new0( tr_torrent_t, 1 ))))
     500    else if(!(( tor = tr_new0( tr_torrent, 1 ))))
    446501        *error = TR_EOTHER;
    447502    else {
     
    457512                     const char         * hashStr,
    458513                     const char         * destination,
    459                      tr_info_t          * setme_info )
     514                     tr_info          * setme_info )
    460515{
    461516    int ret, doFree;
    462     tr_info_t tmp;
     517    tr_info tmp;
    463518
    464519    if( setme_info == NULL )
    465520        setme_info = &tmp;
    466521
    467     memset( setme_info, 0, sizeof( tr_info_t ) );
     522    memset( setme_info, 0, sizeof( tr_info ) );
    468523    ret = tr_metainfoParseHash( setme_info, h->tag, hashStr );
    469524    doFree = !ret && (setme_info == &tmp);
     
    478533}
    479534
    480 tr_torrent_t *
     535tr_torrent *
    481536tr_torrentInitSaved( tr_handle_t    * h,
    482537                     const char     * hashStr,
     
    487542    int val;
    488543    int tmpError;
    489     tr_torrent_t * tor = NULL;
     544    tr_torrent * tor = NULL;
    490545
    491546    if( !error )
     
    494549    if(( val = tr_torrentParseHash( h, hashStr, destination, NULL )))
    495550        *error = val;
    496     else if(!(( tor = tr_new0( tr_torrent_t, 1 ))))
     551    else if(!(( tor = tr_new0( tr_torrent, 1 ))))
    497552        *error = TR_EOTHER;
    498553    else {
     
    509564                     size_t               size,
    510565                     const char         * destination,
    511                      tr_info_t          * setme_info )
     566                     tr_info          * setme_info )
    512567{
    513568    int ret, doFree;
    514     tr_info_t tmp;
     569    tr_info tmp;
    515570
    516571    if( setme_info == NULL )
    517572        setme_info = &tmp;
    518573
    519     memset( setme_info, 0, sizeof( tr_info_t ) );
     574    memset( setme_info, 0, sizeof( tr_info ) );
    520575    ret = tr_metainfoParseData( setme_info, h->tag, data, size, FALSE );
    521576    doFree = !ret && (setme_info == &tmp);
     
    530585}
    531586
    532 tr_torrent_t *
     587tr_torrent *
    533588tr_torrentInitData( tr_handle_t    * h,
    534589                    const uint8_t  * data,
     
    540595    int val;
    541596    int tmpError;
    542     tr_torrent_t * tor = NULL;
     597    tr_torrent * tor = NULL;
    543598
    544599    if( !error )
     
    547602    if(( val = tr_torrentParseData( h, data, size, destination, NULL )))
    548603        *error = val;
    549     else if(!(( tor = tr_new0( tr_torrent_t, 1 ))))
     604    else if(!(( tor = tr_new0( tr_torrent, 1 ))))
    550605        *error = TR_EOTHER;
    551606    else {
     
    557612}
    558613
    559 const tr_info_t *
    560 tr_torrentInfo( const tr_torrent_t * tor )
     614const tr_info *
     615tr_torrentInfo( const tr_torrent * tor )
    561616{
    562617    return &tor->info;
     
    568623
    569624#if 0
    570 int tr_torrentScrape( tr_torrent_t * tor, int * s, int * l, int * d )
     625int tr_torrentScrape( tr_torrent * tor, int * s, int * l, int * d )
    571626{
    572627    return tr_trackerScrape( tor, s, l, d );
     
    574629#endif
    575630
     631static int
     632saveFastResumeNow( void * vtor )
     633{
     634    tr_torrent * tor = (tr_torrent *) vtor;
     635
     636    tr_fastResumeSave( tor );
     637    recheckCpState( tor );
     638
     639    tr_timerFree( &tor->saveTimer );
     640    return FALSE;
     641}
     642
    576643static void
    577 fastResumeSave( tr_torrent_t * tor )
    578 {
    579     tr_fastResumeSave( tor );
    580     tor->fastResumeDirty = FALSE;
    581 }
    582 
    583 void
    584 tr_torrentSetFolder( tr_torrent_t * tor, const char * path )
     644saveFastResumeSoon( void * vtor )
     645{
     646    tr_torrent * tor = (tr_torrent *) vtor;
     647
     648    if( tor->saveTimer == NULL )
     649        tor->saveTimer = tr_timerNew( tor->handle, saveFastResumeNow, tor, 1000 );
     650}
     651
     652/**
     653***
     654**/
     655
     656void
     657tr_torrentSetFolder( tr_torrent * tor, const char * path )
    585658{
    586659    tr_free( tor->destination );
    587660    tor->destination = tr_strdup( path );
    588     fastResumeSave( tor );
     661    saveFastResumeSoon( tor );
    589662}
    590663
    591664const char*
    592 tr_torrentGetFolder( const tr_torrent_t * tor )
     665tr_torrentGetFolder( const tr_torrent * tor )
    593666{
    594667    return tor->destination;
     
    596669
    597670void
    598 tr_torrentChangeMyPort( tr_torrent_t * tor, int port )
    599 {
    600     tr_torrentWriterLock( tor );
     671tr_torrentChangeMyPort( tr_torrent * tor, int port )
     672{
     673    tr_torrentLock( tor );
    601674
    602675    tor->publicPort = port;
     
    605678        tr_trackerChangeMyPort( tor->tracker );
    606679
    607     tr_torrentWriterUnlock( tor );
    608 }
    609 
    610 /***********************************************************************
    611  * torrentReallyStop
    612  ***********************************************************************
    613  * Joins the download thread and frees/closes everything related to it.
    614  **********************************************************************/
    615 
    616 void tr_torrentDisablePex( tr_torrent_t * tor, int disable )
    617 {
    618     tr_torrentWriterLock( tor );
    619 
    620     if( ! ( TR_FLAG_PRIVATE & tor->info.flags ) )
    621     {
    622         if( tor->pexDisabled != disable )
    623         {
    624             int i;
    625             tor->pexDisabled = disable;
    626             for( i=0; i<tor->peerCount; ++i )
    627                 tr_peerSetPrivate( tor->peers[i], disable );
    628         }
    629     }
    630 
    631     tr_torrentWriterUnlock( tor );
    632 }
    633 
    634 static int tr_didStateChangeTo ( tr_torrent_t * tor, int status )
     680    tr_torrentUnlock( tor );
     681}
     682
     683
     684void
     685tr_torrentDisablePex( tr_torrent * tor, int disable )
     686{
     687    assert( tor != NULL );
     688    assert( disable==0 || disable==1 );
     689    //assert( tor->runStatus != TR_RUN_RUNNING );
     690
     691    /* pex is ALWAYS disabled for private torrents */
     692    if( tor->info.flags & TR_FLAG_PRIVATE )
     693        disable = TRUE;
     694
     695    tor->pexDisabled = disable;
     696}
     697
     698static int tr_didStateChangeTo ( tr_torrent * tor, int status )
    635699{
    636700    int ret;
    637701
    638     tr_torrentWriterLock( tor );
     702    tr_torrentLock( tor );
    639703    if (( ret = tor->hasChangedState == status ))
    640704        tor->hasChangedState = -1;
    641     tr_torrentWriterUnlock( tor );
     705    tr_torrentUnlock( tor );
    642706
    643707    return ret;
    644708}
    645709
    646 int tr_getIncomplete( tr_torrent_t * tor )
     710int tr_getIncomplete( tr_torrent * tor )
    647711{
    648712    return tr_didStateChangeTo( tor, TR_CP_INCOMPLETE );
    649713}
    650 int tr_getDone( tr_torrent_t * tor )
     714int tr_getDone( tr_torrent * tor )
    651715{
    652716    return tr_didStateChangeTo( tor, TR_CP_DONE );
    653717}
    654 int tr_getComplete( tr_torrent_t * tor )
     718int tr_getComplete( tr_torrent * tor )
    655719{
    656720    return tr_didStateChangeTo( tor, TR_CP_COMPLETE );
     
    658722
    659723void
    660 tr_manualUpdate( tr_torrent_t * tor )
     724tr_manualUpdate( tr_torrent * tor )
    661725{
    662726    if( tor->runStatus == TR_RUN_RUNNING )
    663         tr_trackerReannounce( tor->tracker );
     727    tr_trackerReannounce( tor->tracker );
    664728}
    665729int
    666 tr_torrentCanManualUpdate( const tr_torrent_t * tor )
     730tr_torrentCanManualUpdate( const tr_torrent * tor )
    667731{
    668732    return ( tor != NULL )
     
    671735}
    672736
    673 const tr_stat_t *
    674 tr_torrentStat( tr_torrent_t * tor )
    675 {
    676     tr_stat_t * s;
    677     struct tr_tracker_s * tc;
    678     int i;
    679 
    680     tr_torrentReaderLock( tor );
     737const tr_stat *
     738tr_torrentStat( tr_torrent * tor )
     739{
     740    tr_stat * s;
     741    struct tr_tracker * tc;
     742
     743    tr_torrentLock( tor );
    681744
    682745    tor->statCur = ( tor->statCur + 1 ) % 2;
     
    690753    s->tracker = tr_trackerGetAddress( tor->tracker );
    691754
    692     /* peers... */
    693     memset( s->peersFrom, 0, sizeof( s->peersFrom ) );
    694     s->peersTotal          = tor->peerCount;
    695     s->peersConnected      = 0;
    696     s->peersSendingToUs    = 0;
    697     s->peersGettingFromUs  = 0;
    698 
    699     for( i=0; i<tor->peerCount; ++i )
    700     {
    701         const tr_peer_t * peer = tor->peers[i];
    702 
    703         if( tr_peerIsConnected( peer ) )
    704         {
    705             ++s->peersConnected;
    706             ++s->peersFrom[tr_peerIsFrom(peer)];
    707 
    708             if( tr_peerDownloadRate( peer ) > 0.01 )
    709                 ++s->peersSendingToUs;
    710 
    711             if( tr_peerUploadRate( peer ) > 0.01 )
    712                 ++s->peersGettingFromUs;
    713         }
    714     }
     755    tr_peerMgrTorrentStats( tor->handle->peerMgr,
     756                            tor->info.hash,
     757                            &s->peersTotal,
     758                            &s->peersConnected,
     759                            &s->peersSendingToUs,
     760                            &s->peersGettingFromUs,
     761                             s->peersFrom );
    715762
    716763    s->percentComplete = tr_cpPercentComplete ( tor->completion );
     
    719766    s->left = tr_cpLeftUntilDone( tor->completion );
    720767
    721     if( tor->uncheckedPieces )
    722         s->status = tor->runStatus==TR_RUN_CHECKING
    723             ? TR_STATUS_CHECK
    724             : TR_STATUS_CHECK_WAIT;
    725     else switch( tor->runStatus ) {
    726         case TR_RUN_STOPPING: /* fallthrough */
    727         case TR_RUN_STOPPING_NET_WAIT: s->status = TR_STATUS_STOPPING; break;
     768    switch( tor->runStatus ) {
     769        case TR_RUN_CHECKING_WAIT: s->status = TR_STATUS_CHECK_WAIT; break;
     770        case TR_RUN_CHECKING: s->status = TR_STATUS_CHECK; break;
     771        case TR_RUN_STOPPING: s->status = TR_STATUS_STOPPING; break;
    728772        case TR_RUN_STOPPED: s->status = TR_STATUS_STOPPED; break;
    729         case TR_RUN_CHECKING: s->status = TR_STATUS_CHECK; break;
    730773        case TR_RUN_RUNNING: switch( tor->cpStatus ) {
    731774            case TR_CP_INCOMPLETE: s->status = TR_STATUS_DOWNLOAD; break;
     
    773816      : TR_RATIO_NA;
    774817   
    775     tr_torrentReaderUnlock( tor );
     818    tr_torrentUnlock( tor );
    776819
    777820    return s;
     
    783826
    784827static uint64_t
    785 fileBytesCompleted ( const tr_torrent_t * tor, int fileIndex )
    786 {
    787     const tr_file_t * file     =  &tor->info.files[fileIndex];
     828fileBytesCompleted ( const tr_torrent * tor, int fileIndex )
     829{
     830    const tr_file * file     =  &tor->info.files[fileIndex];
    788831    const uint64_t firstBlock       =  file->offset / tor->blockSize;
    789832    const uint64_t firstBlockOffset =  file->offset % tor->blockSize;
     
    825868}
    826869
    827 tr_file_stat_t *
    828 tr_torrentFiles( const tr_torrent_t * tor, int * fileCount )
     870tr_file_stat *
     871tr_torrentFiles( const tr_torrent * tor, int * fileCount )
    829872{
    830873    int i;
    831874    const int n = tor->info.fileCount;
    832     tr_file_stat_t * files = tr_new0( tr_file_stat_t, n );
    833     tr_file_stat_t * walk = files;
     875    tr_file_stat * files = tr_new0( tr_file_stat, n );
     876    tr_file_stat * walk = files;
    834877
    835878    for( i=0; i<n; ++i, ++walk )
    836879    {
    837         const tr_file_t * file = tor->info.files + i;
     880        const tr_file * file = tor->info.files + i;
    838881        cp_status_t cp;
    839882
     
    860903
    861904void
    862 tr_torrentFilesFree( tr_file_stat_t * files, int fileCount UNUSED )
     905tr_torrentFilesFree( tr_file_stat * files, int fileCount UNUSED )
    863906{
    864907    tr_free( files );
     
    869912***/
    870913
    871 tr_peer_stat_t *
    872 tr_torrentPeers( const tr_torrent_t * tor, int * peerCount )
    873 {
    874     tr_peer_stat_t * peers;
    875 
    876     tr_torrentReaderLock( tor );
    877 
    878     *peerCount = tor->peerCount;
    879    
    880     peers = tr_new0( tr_peer_stat_t, tor->peerCount );
    881     if (peers != NULL)
    882     {
    883         tr_peer_t * peer;
    884         struct in_addr * addr;
    885         int i;
    886         for( i=0; i<tor->peerCount; ++i )
    887         {
    888             peer = tor->peers[i];
    889            
    890             addr = tr_peerAddress( peer );
    891             if( NULL != addr )
    892             {
    893                 tr_netNtop( addr, peers[i].addr,
    894                            sizeof( peers[i].addr ) );
    895             }
    896            
    897             peers[i].client           =  tr_peerClient( peer );
    898             peers[i].isConnected      =  tr_peerIsConnected( peer );
    899             peers[i].from             =  tr_peerIsFrom( peer );
    900             peers[i].progress         =  tr_peerProgress( peer );
    901             peers[i].port             =  tr_peerPort( peer );
    902 
    903             peers[i].uploadToRate     =  tr_peerUploadRate( peer );
    904             peers[i].downloadFromRate =  tr_peerDownloadRate( peer );
    905            
    906             peers[i].isDownloading    =  peers[i].uploadToRate > 0.01;
    907             peers[i].isUploading      =  peers[i].downloadFromRate > 0.01;
    908         }
    909     }
    910    
    911     tr_torrentReaderUnlock( tor );
    912    
    913     return peers;
    914 }
    915 
    916 void tr_torrentPeersFree( tr_peer_stat_t * peers, int peerCount UNUSED )
     914tr_peer_stat *
     915tr_torrentPeers( const tr_torrent * tor, int * peerCount )
     916{
     917    return tr_peerMgrPeerStats( tor->handle->peerMgr,
     918                                tor->info.hash, peerCount );
     919}
     920
     921void tr_torrentPeersFree( tr_peer_stat * peers, int peerCount UNUSED )
    917922{
    918923    tr_free( peers );
    919924}
    920925
    921 void tr_torrentAvailability( const tr_torrent_t * tor, int8_t * tab, int size )
    922 {
    923     int i, j, piece;
    924     float interval;
    925 
    926     tr_torrentReaderLock( tor );
    927 
    928     interval = (float)tor->info.pieceCount / (float)size;
    929     for( i = 0; i < size; i++ )
    930     {
    931         piece = i * interval;
    932 
    933         if( tr_cpPieceIsComplete( tor->completion, piece ) )
    934         {
    935             tab[i] = -1;
    936             continue;
    937         }
    938 
    939         tab[i] = 0;
    940         for( j = 0; j < tor->peerCount; j++ )
    941         {
    942             if( tr_peerHasPiece( tor->peers[j], piece ) )
    943             {
    944                 (tab[i])++;
    945             }
    946         }
    947     }
    948 
    949     tr_torrentReaderUnlock( tor );
    950 }
    951 
    952 void tr_torrentAmountFinished( const tr_torrent_t * tor, float * tab, int size )
     926void tr_torrentAvailability( const tr_torrent * tor, int8_t * tab, int size )
     927{
     928    return tr_peerMgrTorrentAvailability( tor->handle->peerMgr,
     929                                          tor->info.hash,
     930                                          tab, size );
     931}
     932
     933void tr_torrentAmountFinished( const tr_torrent * tor, float * tab, int size )
    953934{
    954935    int i;
    955936    float interval;
    956     tr_torrentReaderLock( tor );
     937    tr_torrentLock( tor );
    957938
    958939    interval = (float)tor->info.pieceCount / (float)size;
     
    963944    }
    964945
    965     tr_torrentReaderUnlock( tor );
    966 }
    967 
    968 void
    969 tr_torrentResetTransferStats( tr_torrent_t * tor )
    970 {
    971     tr_torrentWriterLock( tor );
     946    tr_torrentUnlock( tor );
     947}
     948
     949void
     950tr_torrentResetTransferStats( tr_torrent * tor )
     951{
     952    tr_torrentLock( tor );
    972953
    973954    tor->downloadedPrev += tor->downloadedCur;
     
    978959    tor->corruptCur      = 0;
    979960
    980     tr_torrentWriterUnlock( tor );
    981 }
    982 
    983 
    984 void
    985 tr_torrentSetHasPiece( tr_torrent_t * tor, int pieceIndex, int has )
    986 {
    987     tr_torrentWriterLock( tor );
     961    tr_torrentUnlock( tor );
     962}
     963
     964
     965void
     966tr_torrentSetHasPiece( tr_torrent * tor, int pieceIndex, int has )
     967{
     968    tr_torrentLock( tor );
    988969
    989970    if( has )
     
    992973        tr_cpPieceRem( tor->completion, pieceIndex );
    993974
    994     tr_torrentWriterUnlock( tor );
    995 }
    996 
    997 void tr_torrentRemoveSaved( tr_torrent_t * tor )
     975    tr_torrentUnlock( tor );
     976}
     977
     978void tr_torrentRemoveSaved( tr_torrent * tor )
    998979{
    999980    tr_metainfoRemoveSaved( tor->info.hashString, tor->handle->tag );
    1000981}
    1001982
    1002 void tr_torrentRecheck( tr_torrent_t * tor )
     983void tr_torrentRecheck( tr_torrent * tor )
    1003984{
    1004985    if( !tor->uncheckedPieces )
    1005986        tor->uncheckedPieces = tr_bitfieldNew( tor->info.pieceCount );
    1006987    tr_bitfieldAddRange( tor->uncheckedPieces, 0, tor->info.pieceCount );
    1007 }
    1008 
    1009 
    1010 int tr_torrentAttachPeer( tr_torrent_t * tor, tr_peer_t * peer )
    1011 {
    1012     int i;
    1013     tr_peer_t * otherPeer;
    1014 
    1015     assert( tor != NULL );
    1016     assert( peer != NULL );
    1017 
    1018     if( tor->peerCount >= TR_MAX_PEER_COUNT )
    1019     {
    1020         tr_peerDestroy(  peer );
    1021         return 0;
    1022     }
    1023 
    1024     /* Don't accept two connections from the same IP */
    1025     for( i = 0; i < tor->peerCount; i++ )
    1026     {
    1027         otherPeer = tor->peers[i];
    1028         if( !memcmp( tr_peerAddress( peer ), tr_peerAddress( otherPeer ), 4 ) )
    1029         {
    1030             tr_peerDestroy(  peer );
    1031             return 0;
    1032         }
    1033     }
    1034 
    1035     tr_peerSetPrivate( peer, tor->info.flags & TR_FLAG_PRIVATE ||
    1036                        tor->pexDisabled );
    1037     tr_peerSetTorrent( peer, tor );
    1038     tor->peers[tor->peerCount++] = peer;
    1039 
    1040     return 1;
    1041 }
    1042 
    1043 int tr_torrentAddCompact( tr_torrent_t * tor, int from,
    1044                            const uint8_t * buf, int count )
    1045 {
    1046     struct in_addr addr;
    1047     tr_port_t port;
    1048     int i, added;
    1049     tr_peer_t * peer;
    1050 
    1051     added = 0;
    1052     for( i=0; i<count; ++i )
    1053     {
    1054         memcpy( &addr, buf, 4 ); buf += 4;
    1055         memcpy( &port, buf, 2 ); buf += 2;
    1056         peer = tr_peerInit( &addr, port, -1, from );
    1057         added += tr_torrentAttachPeer( tor, peer );
    1058     }
    1059 
    1060     return added;
     988
     989    tr_ioRecheckAdd( tor, recheckDoneCB, tor->runStatus );
    1061990}
    1062991
     
    1065994***/
    1066995
    1067 static void setRunState( tr_torrent_t * tor, run_status_t run )
    1068 {
    1069     tr_torrentWriterLock( tor );
    1070     tor->runStatus = run;
    1071     tr_torrentWriterUnlock( tor );
    1072 }
    1073 
    1074 void tr_torrentStart( tr_torrent_t * tor )
    1075 {
    1076     setRunState( tor, TR_RUN_RUNNING );
    1077 
    1078     tr_trackerStart( tor->tracker );
    1079 }
    1080 
    1081 void tr_torrentStop( tr_torrent_t * tor )
    1082 {
    1083     if((tor->runStatus != TR_RUN_STOPPING) && (tor->runStatus != TR_RUN_STOPPED) )
    1084         setRunState( tor, TR_RUN_STOPPING );
    1085 }
    1086 
    1087 void tr_torrentClose( tr_torrent_t * tor )
    1088 {
    1089     tor->runStatusToSave = tor->runStatus;
    1090     tor->runStatusToSaveIsSet = TRUE;
    1091     tr_torrentStop( tor );
    1092     tor->dieFlag = TRUE;
     996void
     997tr_torrentStart( tr_torrent * tor )
     998{
     999    tr_ioRecheckAdd( tor, recheckDoneCB, TR_RUN_RUNNING );
    10931000}
    10941001
    10951002static void
    1096 tr_torrentFree( tr_torrent_t * tor )
    1097 {
    1098     tr_torrent_t * t;
     1003tr_torrentFree( tr_torrent * tor )
     1004{
     1005    tr_torrent * t;
    10991006    tr_handle_t * h = tor->handle;
    1100     tr_info_t * inf = &tor->info;
     1007    tr_info * inf = &tor->info;
     1008fprintf( stderr, "closing torrent %s\n", tor->info.name );
     1009
     1010    assert( tor != NULL );
     1011    assert( tor->runStatus == TR_RUN_STOPPED );
    11011012
    11021013    tr_sharedLock( h->shared );
    11031014
    1104     tr_rwFree( tor->lock );
     1015    tr_lockFree( tor->lock );
    11051016    tr_cpClose( tor->completion );
    11061017
     
    11141025
    11151026    tr_free( tor->destination );
    1116 
    1117     tr_metainfoFree( inf );
    11181027
    11191028    if( tor == h->torrentList )
     
    11261035    }
    11271036
     1037    assert( h->torrentCount >= 1 );
    11281038    h->torrentCount--;
    11291039
     
    11311041            tor->info.name, h->torrentCount );
    11321042
     1043    tr_peerMgrRemoveTorrent( h->peerMgr, tor->info.hash );
     1044
     1045    tr_metainfoFree( inf );
    11331046    tr_free( tor );
    11341047
     
    11361049}
    11371050
     1051static int
     1052freeWhenStopped( void * vtor )
     1053{
     1054    tr_torrent * tor = vtor;
     1055
     1056    if( tor->runStatus != TR_RUN_STOPPED ) /* keep waiting */
     1057        return TRUE;
     1058
     1059    tr_torrentFree( tor );
     1060    return FALSE;
     1061}
     1062
    11381063static void
    1139 recheckCpState( tr_torrent_t * tor )
     1064tr_torrentStopImpl( void * vtor )
     1065{
     1066    tr_torrent * tor = vtor;
     1067
     1068    switch( tor->runStatus )
     1069    {
     1070        case TR_RUN_CHECKING_WAIT:
     1071        case TR_RUN_CHECKING:
     1072            tr_ioRecheckRemove( tor );
     1073            tr_torrentStop( tor );
     1074            break;
     1075
     1076        case TR_RUN_RUNNING:
     1077            saveFastResumeNow( tor );
     1078            tr_peerMgrStopTorrent( tor->handle->peerMgr, tor->info.hash );
     1079            tor->runStatus = TR_RUN_STOPPING;
     1080            tor->stopDate = tr_date( );
     1081            tr_trackerStop( tor->tracker );
     1082            tr_ioClose( tor );
     1083            break;
     1084
     1085        case TR_RUN_STOPPING:
     1086        case TR_RUN_STOPPED:
     1087            break;
     1088    }
     1089}
     1090
     1091void
     1092tr_torrentStop( tr_torrent * tor )
     1093{
     1094    tr_runInEventThread( tor->handle, tr_torrentStopImpl, tor );
     1095}
     1096
     1097void
     1098tr_torrentClose( tr_torrent * tor )
     1099{
     1100    tor->runStatusToSave = tor->runStatus;
     1101    tor->runStatusToSaveIsSet = TRUE;
     1102    tor->dieFlag = TRUE;
     1103    tr_torrentStop( tor );
     1104    tr_timerNew( tor->handle, freeWhenStopped, tor, 250 );
     1105}
     1106
     1107static void
     1108recheckCpState( tr_torrent * tor )
    11401109{
    11411110    cp_status_t cpStatus;
    11421111
    1143     tr_torrentWriterLock( tor );
     1112    tr_torrentLock( tor );
    11441113
    11451114    cpStatus = tr_cpGetStatus( tor->completion );
     
    11511120            tr_trackerCompleted( tor->tracker ); /* tell the tracker */
    11521121        }
    1153         tr_ioSync( tor->io );
    1154         fastResumeSave( tor );
    1155     }
    1156     tr_torrentWriterUnlock( tor );
    1157 }
    1158 
    1159 static void
    1160 torrentThreadLoop ( void * _tor )
    1161 {
    1162     static tr_lock_t * checkFilesLock = NULL;
    1163     tr_torrent_t * tor = _tor;
    1164 
    1165     /* create the check-files mutex */
    1166     if( !checkFilesLock )
    1167          checkFilesLock = tr_lockNew( );
    1168 
    1169     /* loop until the torrent is being deleted */
    1170     while( ! ( tor->dieFlag && (tor->runStatus == TR_RUN_STOPPED) ) )
    1171     {
    1172         /* sleep a little while */
    1173         tr_wait( tor->runStatus == TR_RUN_STOPPED ? 1600 : 600 );
    1174 
    1175         if( tor->fastResumeDirty )
    1176         {
    1177             fastResumeSave( tor );
    1178             recheckCpState( tor );
    1179         }
    1180 
    1181         /* if we're stopping... */
    1182         if( tor->runStatus == TR_RUN_STOPPING )
    1183         {
    1184             int i;
    1185             tr_torrentWriterLock( tor );
    1186 
    1187             /* close the IO */
    1188             tr_ioClose( tor->io );
    1189             tor->io = NULL;
    1190             fastResumeSave( tor );
    1191 
    1192             /* close the peers */
    1193             for( i=0; i<tor->peerCount; ++i )
    1194                 tr_peerDestroy( tor->peers[i] );
    1195             tor->peerCount = 0;
    1196 
    1197             /* resest the transfer rates */
    1198             tr_rcReset( tor->download );
    1199             tr_rcReset( tor->upload );
    1200             tr_rcReset( tor->swarmspeed );
    1201 
    1202             /* tell the tracker we're stopping */
    1203             tr_trackerStop( tor->tracker );
    1204             tor->runStatus = TR_RUN_STOPPING_NET_WAIT;
    1205             tor->stopDate = tr_date();
    1206             tr_torrentWriterUnlock( tor );
    1207         }
    1208 
    1209         if( tor->runStatus == TR_RUN_STOPPING_NET_WAIT )
    1210         {
    1211 #if 0
    1212             tr_torrentWriterLock( tor );
    1213             tor->runStatus = TR_RUN_STOPPED;
    1214             tr_torrentWriterUnlock( tor );
    1215 #endif
    1216             continue;
    1217         }
    1218 
    1219         /* do we need to check files? */
    1220         if( tor->uncheckedPieces )
    1221         {
    1222             if( !tr_lockTryLock( checkFilesLock ) )
    1223             {
    1224                 run_status_t realStatus;
    1225 
    1226                 tr_torrentWriterLock( tor );
    1227                 realStatus = tor->runStatus;
    1228                 tor->runStatus = TR_RUN_CHECKING;
    1229                 tr_torrentWriterUnlock( tor );
    1230 
    1231                 tr_ioCheckFiles( tor );
    1232                 setRunState( tor, realStatus );
    1233 
    1234                 tr_torrentWriterLock( tor );
    1235                 tor->cpStatus = tr_cpGetStatus( tor->completion );
    1236                 tr_torrentWriterUnlock( tor );
    1237 
    1238                 tr_lockUnlock( checkFilesLock );
    1239             }
    1240             continue;
    1241         }
    1242 
    1243         /* if we're paused or stopped, not much to do... */
    1244         if( tor->runStatus == TR_RUN_STOPPED )
    1245             continue;
    1246 
    1247         /* ping our peers if we're running... */
    1248         if( tor->runStatus == TR_RUN_RUNNING )
    1249         {
    1250             int i;
    1251 
    1252             /* starting to run... */
    1253             if( tor->io == NULL )
    1254             {
    1255                 *tor->errorString = '\0';
    1256                 tr_torrentResetTransferStats( tor );
    1257                 tor->io = tr_ioNew( tor );
    1258                 tor->startDate = tr_date();
    1259             }
    1260 
    1261             /* refresh our completion state */
    1262             recheckCpState( tor );
    1263 
    1264             /* Shuffle peers */
    1265             if ( tor->peerCount > 1 ) {
    1266                 tr_peer_t * tmp = tor->peers[0];
    1267                 memmove( tor->peers, tor->peers+1,
    1268                         (tor->peerCount-1) * sizeof(void*) );
    1269                 tor->peers[tor->peerCount - 1] = tmp;
    1270             }
    1271 
    1272             /* receive/send messages */
    1273             tr_torrentWriterLock( tor );
    1274             for( i=0; i<tor->peerCount; ) {
    1275                 tr_peer_t * peer = tor->peers[i];
    1276                 int ret = tr_peerPulse( peer );
    1277                 if( ret & TR_ERROR_IO_MASK ) {
    1278                     tr_err( "Fatal error, stopping download (%d)", ret );
    1279                     tor->runStatus = TR_RUN_STOPPING;
    1280                     tor->error = ret;
    1281                     strlcpy( tor->errorString,
    1282                              tr_errorString(ret),
    1283                              sizeof(tor->errorString) );
    1284                     break;
    1285                 }
    1286                 if( ret ) {
    1287                     tr_peerDestroy( peer );
    1288                     tor->peerCount--;
    1289                     memmove( &tor->peers[i], &tor->peers[i+1],
    1290                              (tor->peerCount-i)*sizeof(void*) );
    1291                     continue;
    1292                 }
    1293                 i++;
    1294             }
    1295             tr_torrentWriterUnlock( tor );
    1296         }
    1297     }
    1298 
    1299     tr_ioClose( tor->io );
    1300     tr_torrentFree( tor );
    1301 }
    1302 
     1122        tr_ioClose( tor );
     1123        saveFastResumeSoon( tor );
     1124    }
     1125    tr_torrentUnlock( tor );
     1126}
    13031127
    13041128/**
     
    13071131
    13081132void
    1309 tr_torrentSetFilePriority( tr_torrent_t   * tor,
    1310                            int              fileIndex,
    1311                            tr_priority_t    priority )
     1133tr_torrentSetFilePriority( tr_torrent   * tor,
     1134                           int            fileIndex,
     1135                           tr_priority_t  priority )
    13121136{
    13131137    int i;
    1314     tr_file_t * file;
    1315 
    1316     tr_torrentWriterLock( tor );
     1138    tr_file * file;
     1139
     1140    tr_torrentLock( tor );
    13171141
    13181142    assert( tor != NULL );
     
    13291153             priority, tor->info.files[fileIndex].name );
    13301154
    1331     tor->fastResumeDirty = TRUE;
    1332 
    1333     tr_torrentWriterUnlock( tor );
    1334 }
    1335 
    1336 void
    1337 tr_torrentSetFilePriorities( tr_torrent_t        * tor,
    1338                              int                 * files,
    1339                              int                   fileCount,
    1340                              tr_priority_t         priority )
     1155    saveFastResumeSoon( tor );
     1156
     1157    tr_torrentUnlock( tor );
     1158}
     1159
     1160void
     1161tr_torrentSetFilePriorities( tr_torrent     * tor,
     1162                             int            * files,
     1163                             int              fileCount,
     1164                             tr_priority_t    priority )
    13411165{
    13421166    int i;
     
    13461170
    13471171tr_priority_t
    1348 tr_torrentGetFilePriority( const tr_torrent_t *  tor, int file )
     1172tr_torrentGetFilePriority( const tr_torrent *  tor, int file )
    13491173{
    13501174    tr_priority_t ret;
    13511175
    1352     tr_torrentReaderLock( tor );
     1176    tr_torrentLock( tor );
    13531177    assert( tor != NULL );
    13541178    assert( 0<=file && file<tor->info.fileCount );
    13551179    ret = tor->info.files[file].priority;
    1356     tr_torrentReaderUnlock( tor );
     1180    tr_torrentUnlock( tor );
    13571181
    13581182    return ret;
     
    13611185
    13621186tr_priority_t*
    1363 tr_torrentGetFilePriorities( const tr_torrent_t * tor )
     1187tr_torrentGetFilePriorities( const tr_torrent * tor )
    13641188{
    13651189    int i;
    13661190    tr_priority_t * p;
    13671191
    1368     tr_torrentReaderLock( tor );
     1192    tr_torrentLock( tor );
    13691193    p = tr_new0( tr_priority_t, tor->info.fileCount );
    13701194    for( i=0; i<tor->info.fileCount; ++i )
    13711195        p[i] = tor->info.files[i].priority;
    1372     tr_torrentReaderUnlock( tor );
     1196    tr_torrentUnlock( tor );
    13731197
    13741198    return p;
     
    13801204
    13811205int
    1382 tr_torrentGetFileDL( const tr_torrent_t * tor,
    1383                      int                  file )
     1206tr_torrentGetFileDL( const tr_torrent * tor,
     1207                     int                file )
    13841208{
    13851209    int doDownload;
    1386     tr_torrentReaderLock( tor );
     1210    tr_torrentLock( tor );
    13871211
    13881212    assert( 0<=file && file<tor->info.fileCount );
    13891213    doDownload = !tor->info.files[file].dnd;
    13901214