Ignore:
Timestamp:
Jan 21, 2007, 7:16:18 AM (15 years ago)
Author:
titer
Message:

Officially give up on making libT reentrant, and simplify our code instead

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/fdlimit.c

    r1408 r1420  
    2929                                connections to trackers */
    3030
     31/***********************************************************************
     32 * Structures
     33 **********************************************************************/
    3134typedef struct tr_openFile_s
    3235{
     
    4346
    4447    uint64_t   date;
    45 
    46 } tr_openFile_t;
    47 
    48 struct tr_fd_s
     48}
     49tr_openFile_t;
     50
     51typedef struct tr_fd_s
    4952{
    5053    tr_lock_t       lock;
     
    5760
    5861    tr_openFile_t   open[TR_MAX_OPEN_FILES];
    59 };
     62}
     63tr_fd_t;
     64
     65static tr_fd_t * gFd = NULL;
    6066
    6167/***********************************************************************
     
    6369 **********************************************************************/
    6470static int  ErrorFromErrno();
    65 static int  OpenFile( tr_fd_t * f, int i, char * folder, char * name,
    66                       int write );
    67 static void CloseFile( tr_fd_t * f, int i );
     71static int  OpenFile( int i, char * folder, char * name, int write );
     72static void CloseFile( int i );
    6873
    6974
     
    7176 * tr_fdInit
    7277 **********************************************************************/
    73 tr_fd_t * tr_fdInit()
    74 {
    75     tr_fd_t * f;
     78void tr_fdInit()
     79{
    7680    int i, j, s[4096];
    7781
    78     f = calloc( sizeof( tr_fd_t ), 1 );
     82    if( gFd )
     83    {
     84        tr_err( "tr_fdInit was called before!" );
     85        return;
     86    }
     87
     88    gFd = calloc( sizeof( tr_fd_t ), 1 );
    7989
    8090    /* Init lock and cond */
    81     tr_lockInit( &f->lock );
    82     tr_condInit( &f->cond );
     91    tr_lockInit( &gFd->lock );
     92    tr_condInit( &gFd->cond );
    8393
    8494    /* Detect the maximum number of open files or sockets */
     
    97107    tr_dbg( "%d usable file descriptors", i );
    98108
    99     f->reserved  = 0;
    100     f->normal    = 0;
    101 
    102     f->normalMax = i - TR_RESERVED_FDS - 10;
     109    gFd->reserved  = 0;
     110    gFd->normal    = 0;
     111
     112    gFd->normalMax = i - TR_RESERVED_FDS - 10;
    103113        /* To be safe, in case the UI needs to write a preferences file
    104114           or something */
     
    106116    for( i = 0; i < TR_MAX_OPEN_FILES; i++ )
    107117    {
    108         f->open[i].status = STATUS_INVALID;
    109     }
    110 
    111     return f;
     118        gFd->open[i].status = STATUS_INVALID;
     119    }
    112120}
    113121
     
    115123 * tr_fdFileOpen
    116124 **********************************************************************/
    117 int tr_fdFileOpen( tr_fd_t * f, char * folder, char * name, int write )
     125int tr_fdFileOpen( char * folder, char * name, int write )
    118126{
    119127    int i, winner, ret;
    120128    uint64_t date;
    121129
    122     tr_lockLock( &f->lock );
     130    tr_lockLock( &gFd->lock );
    123131
    124132    /* Is it already open? */
    125133    for( i = 0; i < TR_MAX_OPEN_FILES; i++ )
    126134    {
    127         if( f->open[i].status & STATUS_INVALID ||
    128             strcmp( folder, f->open[i].folder ) ||
    129             strcmp( name, f->open[i].name ) )
     135        if( gFd->open[i].status & STATUS_INVALID ||
     136            strcmp( folder, gFd->open[i].folder ) ||
     137            strcmp( name, gFd->open[i].name ) )
    130138        {
    131139            continue;
    132140        }
    133         if( f->open[i].status & STATUS_CLOSING )
     141        if( gFd->open[i].status & STATUS_CLOSING )
    134142        {
    135143            /* File is being closed by another thread, wait until
    136144             * it's done before we reopen it */
    137             tr_condWait( &f->cond, &f->lock );
     145            tr_condWait( &gFd->cond, &gFd->lock );
    138146            i = -1;
    139147            continue;
    140148        }
    141         if( f->open[i].write < write )
     149        if( gFd->open[i].write < write )
    142150        {
    143151            /* File is open read-only and needs to be closed then
    144152             * re-opened read-write */
    145             CloseFile( f, i );
     153            CloseFile( i );
    146154            continue;
    147155        }
     
    153161    for( i = 0; i < TR_MAX_OPEN_FILES; i++ )
    154162    {
    155         if( f->open[i].status & STATUS_INVALID )
     163        if( gFd->open[i].status & STATUS_INVALID )
    156164        {
    157165            winner = i;
     
    168176        for( i = 0; i < TR_MAX_OPEN_FILES; i++ )
    169177        {
    170             if( !( f->open[i].status & STATUS_UNUSED ) )
     178            if( !( gFd->open[i].status & STATUS_UNUSED ) )
    171179            {
    172180                continue;
    173181            }
    174             if( f->open[i].date < date )
     182            if( gFd->open[i].date < date )
    175183            {
    176184                winner = i;
    177                 date   = f->open[i].date;
     185                date   = gFd->open[i].date;
    178186            }
    179187        }
     
    181189        if( winner >= 0 )
    182190        {
    183             CloseFile( f, winner );
     191            CloseFile( winner );
    184192            goto open;
    185193        }
    186194
    187195        /* All used! Wait a bit and try again */
    188         tr_condWait( &f->cond, &f->lock );
     196        tr_condWait( &gFd->cond, &gFd->lock );
    189197    }
    190198
    191199open:
    192     if( ( ret = OpenFile( f, winner, folder, name, write ) ) )
    193     {
    194         tr_lockUnlock( &f->lock );
     200    if( ( ret = OpenFile( winner, folder, name, write ) ) )
     201    {
     202        tr_lockUnlock( &gFd->lock );
    195203        return ret;
    196204    }
    197     snprintf( f->open[winner].folder, MAX_PATH_LENGTH, "%s", folder );
    198     snprintf( f->open[winner].name, MAX_PATH_LENGTH, "%s", name );
    199     f->open[winner].write = write;
     205    snprintf( gFd->open[winner].folder, MAX_PATH_LENGTH, "%s", folder );
     206    snprintf( gFd->open[winner].name, MAX_PATH_LENGTH, "%s", name );
     207    gFd->open[winner].write = write;
    200208
    201209done:
    202     f->open[winner].status = STATUS_USED;
    203     f->open[winner].date   = tr_date();
    204     tr_lockUnlock( &f->lock );
     210    gFd->open[winner].status = STATUS_USED;
     211    gFd->open[winner].date   = tr_date();
     212    tr_lockUnlock( &gFd->lock );
    205213   
    206     return f->open[winner].file;
     214    return gFd->open[winner].file;
    207215}
    208216
     
    210218 * tr_fdFileRelease
    211219 **********************************************************************/
    212 void tr_fdFileRelease( tr_fd_t * f, int file )
     220void tr_fdFileRelease( int file )
    213221{
    214222    int i;
    215     tr_lockLock( &f->lock );
     223    tr_lockLock( &gFd->lock );
    216224
    217225    for( i = 0; i < TR_MAX_OPEN_FILES; i++ )
    218226    {
    219         if( f->open[i].file == file )
    220         {
    221             f->open[i].status = STATUS_UNUSED;
     227        if( gFd->open[i].file == file )
     228        {
     229            gFd->open[i].status = STATUS_UNUSED;
    222230            break;
    223231        }
    224232    }
    225233   
    226     tr_condSignal( &f->cond );
    227     tr_lockUnlock( &f->lock );
     234    tr_condSignal( &gFd->cond );
     235    tr_lockUnlock( &gFd->lock );
    228236}
    229237
     
    231239 * tr_fdFileClose
    232240 **********************************************************************/
    233 void tr_fdFileClose( tr_fd_t * f, char * folder, char * name )
     241void tr_fdFileClose( char * folder, char * name )
    234242{
    235243    int i;
    236244
    237     tr_lockLock( &f->lock );
     245    tr_lockLock( &gFd->lock );
    238246
    239247    for( i = 0; i < TR_MAX_OPEN_FILES; i++ )
    240248    {
    241         if( f->open[i].status & STATUS_INVALID )
     249        if( gFd->open[i].status & STATUS_INVALID )
    242250        {
    243251            continue;
    244252        }
    245         if( !strcmp( folder, f->open[i].folder ) &&
    246             !strcmp( name, f->open[i].name ) )
    247         {
    248             CloseFile( f, i );
    249         }
    250     }
    251 
    252     tr_lockUnlock( &f->lock );
     253        if( !strcmp( folder, gFd->open[i].folder ) &&
     254            !strcmp( name, gFd->open[i].name ) )
     255        {
     256            CloseFile( i );
     257        }
     258    }
     259
     260    tr_lockUnlock( &gFd->lock );
    253261}
    254262
     
    256264 * tr_fdSocketWillCreate
    257265 **********************************************************************/
    258 int tr_fdSocketWillCreate( tr_fd_t * f, int reserved )
     266int tr_fdSocketWillCreate( int reserved )
    259267{
    260268    int ret;
    261269
    262     tr_lockLock( &f->lock );
     270    tr_lockLock( &gFd->lock );
    263271
    264272    if( reserved )
    265273    {
    266         if( f->reserved < TR_RESERVED_FDS )
     274        if( gFd->reserved < TR_RESERVED_FDS )
    267275        {
    268276            ret = 0;
    269             (f->reserved)++;
     277            (gFd->reserved)++;
    270278        }
    271279        else
     
    276284    else
    277285    {
    278         if( f->normal < f->normalMax )
     286        if( gFd->normal < gFd->normalMax )
    279287        {
    280288            ret = 0;
    281             (f->normal)++;
     289            (gFd->normal)++;
    282290        }
    283291        else
     
    287295    }
    288296
    289     tr_lockUnlock( &f->lock );
     297    tr_lockUnlock( &gFd->lock );
    290298
    291299    return ret;
     
    295303 * tr_fdSocketClosed
    296304 **********************************************************************/
    297 void tr_fdSocketClosed( tr_fd_t * f, int reserved )
    298 {
    299     tr_lockLock( &f->lock );
     305void tr_fdSocketClosed( int reserved )
     306{
     307    tr_lockLock( &gFd->lock );
    300308
    301309    if( reserved )
    302310    {
    303         (f->reserved)--;
     311        (gFd->reserved)--;
    304312    }
    305313    else
    306314    {
    307         (f->normal)--;
    308     }
    309 
    310     tr_lockUnlock( &f->lock );
     315        (gFd->normal)--;
     316    }
     317
     318    tr_lockUnlock( &gFd->lock );
    311319}
    312320
     
    314322 * tr_fdClose
    315323 **********************************************************************/
    316 void tr_fdClose( tr_fd_t * f )
    317 {
    318     tr_lockClose( &f->lock );
    319     tr_condClose( &f->cond );
    320     free( f );
     324void tr_fdClose()
     325{
     326    tr_lockClose( &gFd->lock );
     327    tr_condClose( &gFd->cond );
     328    free( gFd );
    321329}
    322330
     
    341349 *
    342350 **********************************************************************/
    343 static int OpenFile( tr_fd_t * f, int i, char * folder, char * name,
    344                      int write )
    345 {
    346     tr_openFile_t * file = &f->open[i];
     351static int OpenFile( int i, char * folder, char * name, int write )
     352{
     353    tr_openFile_t * file = &gFd->open[i];
    347354    struct stat sb;
    348355    char * path;
     
    411418 * threads.
    412419 **********************************************************************/
    413 static void CloseFile( tr_fd_t * f, int i )
    414 {
    415     tr_openFile_t * file = &f->open[i];
     420static void CloseFile( int i )
     421{
     422    tr_openFile_t * file = &gFd->open[i];
    416423
    417424    /* If it's already being closed by another thread, just wait till
     
    419426    while( file->status & STATUS_CLOSING )
    420427    {
    421         tr_condWait( &f->cond, &f->lock );
     428        tr_condWait( &gFd->cond, &gFd->lock );
    422429    }
    423430    if( file->status & STATUS_INVALID )
     
    433440    tr_dbg( "Closing %s in %s (%d)", file->name, file->folder, file->write );
    434441    file->status = STATUS_CLOSING;
    435     tr_lockUnlock( &f->lock );
     442    tr_lockUnlock( &gFd->lock );
    436443    close( file->file );
    437     tr_lockLock( &f->lock );
     444    tr_lockLock( &gFd->lock );
    438445    file->status = STATUS_INVALID;
    439     tr_condSignal( &f->cond );
    440 }
    441 
     446    tr_condSignal( &gFd->cond );
     447}
     448
Note: See TracChangeset for help on using the changeset viewer.