Changeset 1199


Ignore:
Timestamp:
Dec 13, 2006, 8:27:00 PM (15 years ago)
Author:
titer
Message:

Updates implementation (not complete yet)

Location:
branches/io/libtransmission
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/io/libtransmission/fdlimit.c

    r261 r1199  
    3131typedef struct tr_openFile_s
    3232{
    33     char       path[MAX_PATH_LENGTH];
     33    char       folder[MAX_PATH_LENGTH];
     34    char       name[MAX_PATH_LENGTH];
    3435    int        file;
     36    int        write;
    3537
    3638#define STATUS_INVALID 1
     
    5759
    5860/***********************************************************************
     61 * Local prototypes
     62 **********************************************************************/
     63static void CloseFile( tr_fd_t * f, int i );
     64static int  CheckCanOpen( char * folder, char * name, int write );
     65
     66
     67
     68/***********************************************************************
    5969 * tr_fdInit
    6070 **********************************************************************/
     
    102112 * tr_fdFileOpen
    103113 **********************************************************************/
    104 int tr_fdFileOpen( tr_fd_t * f, char * path )
    105 {
    106     int i, winner;
     114int tr_fdFileOpen( tr_fd_t * f, char * folder, char * name, int write )
     115{
     116    int i, winner, ret;
    107117    uint64_t date;
     118    char * path;
    108119
    109120    tr_lockLock( &f->lock );
     
    112123    for( i = 0; i < TR_MAX_OPEN_FILES; i++ )
    113124    {
    114         if( f->open[i].status > STATUS_INVALID &&
    115             !strcmp( path, f->open[i].path ) )
    116         {
    117             if( f->open[i].status & STATUS_CLOSING )
    118             {
    119                 /* Wait until the file is closed */
    120                 tr_lockUnlock( &f->lock );
    121                 tr_wait( 10 );
    122                 tr_lockLock( &f->lock );
    123                 i = -1;
    124                 continue;
    125             }
    126             winner = i;
    127             goto done;
    128         }
     125        if( f->open[i].status & STATUS_INVALID ||
     126            strcmp( folder, f->open[i].folder ) ||
     127            strcmp( name, f->open[i].name ) )
     128        {
     129            continue;
     130        }
     131        if( f->open[i].status & STATUS_CLOSING )
     132        {
     133            /* File is being closed by another thread, wait until
     134             * it's done before we reopen it */
     135            tr_lockUnlock( &f->lock );
     136            tr_wait( 10 );
     137            tr_lockLock( &f->lock );
     138            i = -1;
     139            continue;
     140        }
     141        if( f->open[i].write < write )
     142        {
     143            /* File is open read-only and needs to be closed then
     144             * re-opened read-write */
     145            CloseFile( f, i );
     146            continue;
     147        }
     148        winner = i;
     149        goto done;
     150    }
     151
     152    /* We'll need to open it, make sure that we can */
     153    if( ( ret = CheckCanOpen( folder, name, write ) ) )
     154    {
     155        tr_err( "Can not open %s in %s (%d)", name, folder, ret );
     156        tr_lockUnlock( &f->lock );
     157        return ret;
    129158    }
    130159
     
    160189        if( winner >= 0 )
    161190        {
    162             /* Close the file: we mark it as closing then release the
    163                lock while doing so, because close may take same time
    164                and we don't want to block other threads */
    165             tr_dbg( "Closing %s", f->open[winner].path );
    166             f->open[winner].status = STATUS_CLOSING;
    167             tr_lockUnlock( &f->lock );
    168             close( f->open[winner].file );
    169             tr_lockLock( &f->lock );
     191            CloseFile( f, winner );
    170192            goto open;
    171193        }
     
    178200
    179201open:
    180     tr_dbg( "Opening %s", path );
    181     snprintf( f->open[winner].path, MAX_PATH_LENGTH, "%s", path );
    182     f->open[winner].file = open( path, O_RDWR, 0 );
     202    tr_dbg( "Opening %s in %s", name, folder );
     203    asprintf( &path, "%s/%s", folder, name );
     204    f->open[winner].file = open( path, write ? O_RDWR : O_RDONLY, 0 );
     205    free( path );
     206    if( f->open[winner].file < 0 )
     207    {
     208        tr_err( "Could not open %s in %s (%d)", name, folder, errno );
     209        tr_lockUnlock( &f->lock );
     210        return TR_ERROR_IO_OTHER;
     211    }
     212    snprintf( f->open[winner].folder, MAX_PATH_LENGTH, "%s", folder );
     213    snprintf( f->open[winner].name, MAX_PATH_LENGTH, "%s", name );
     214    f->open[winner].write = write;
    183215
    184216done:
     
    213245 * tr_fdFileClose
    214246 **********************************************************************/
    215 void tr_fdFileClose( tr_fd_t * f, char * path )
     247void tr_fdFileClose( tr_fd_t * f, char * folder, char * name )
    216248{
    217249    int i;
     
    226258            continue;
    227259        }
    228         if( !strcmp( path, f->open[i].path ) )
    229         {
    230             tr_dbg( "Closing %s", path );
    231             close( f->open[i].file );
    232             f->open[i].status = STATUS_INVALID;
    233             break;
    234         }
    235     }
    236 
    237     tr_lockUnlock( &f->lock );
    238 }
    239 
     260        if( !strcmp( folder, f->open[i].folder ) &&
     261            !strcmp( name, f->open[i].name ) )
     262        {
     263            CloseFile( f, i );
     264        }
     265    }
     266
     267    tr_lockUnlock( &f->lock );
     268}
     269
     270/***********************************************************************
     271 * tr_fdSocketWillCreate
     272 **********************************************************************/
    240273int tr_fdSocketWillCreate( tr_fd_t * f, int reserved )
    241274{
     
    274307}
    275308
     309/***********************************************************************
     310 * tr_fdSocketClosed
     311 **********************************************************************/
    276312void tr_fdSocketClosed( tr_fd_t * f, int reserved )
    277313{
     
    290326}
    291327
     328/***********************************************************************
     329 * tr_fdClose
     330 **********************************************************************/
    292331void tr_fdClose( tr_fd_t * f )
    293332{
     
    296335}
    297336
     337
     338/***********************************************************************
     339 * Local functions
     340 **********************************************************************/
     341
     342/***********************************************************************
     343 * CloseFile
     344 ***********************************************************************
     345 * We first mark it as closing then release the lock while doing so,
     346 * because close() may take same time and we don't want to block other
     347 * threads.
     348 **********************************************************************/
     349static void CloseFile( tr_fd_t * f, int i )
     350{
     351    if( !( f->open[i].status & STATUS_UNUSED ) )
     352    {
     353        tr_err( "CloseFile: status is %d, should be %d",
     354                f->open[i].status, STATUS_UNUSED );
     355    }
     356    tr_dbg( "Closing %s in %s", f->open[i].name, f->open[i].folder );
     357    f->open[i].status = STATUS_CLOSING;
     358    tr_lockUnlock( &f->lock );
     359    close( f->open[i].file );
     360    tr_lockLock( &f->lock );
     361    f->open[i].status = STATUS_INVALID;
     362}
     363
     364/***********************************************************************
     365 * CheckCanOpen
     366 ***********************************************************************
     367 *
     368 **********************************************************************/
     369static int CheckCanOpen( char * folder, char * name, int write )
     370{
     371    return 0;
     372}
  • branches/io/libtransmission/fdlimit.h

    r1198 r1199  
    3838 * directory 'folder'. If 'name' itself contains '/'s, required
    3939 * subfolders are created. The file is open read-write if 'write' is 1
    40  * (created if necessary), read-only otherwise.
     40 * (created if necessary), read-only if 0.
    4141 * Returns the file descriptor if successful, otherwise returns
    4242 * one of the TR_ERROR_IO_*.
Note: See TracChangeset for help on using the changeset viewer.