Changeset 3917


Ignore:
Timestamp:
Nov 21, 2007, 4:16:57 PM (15 years ago)
Author:
charles
Message:

0.9x: fix ticket #451 (Files remain in use after removal)

Location:
branches/0.9x/libtransmission
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/0.9x/libtransmission/fdlimit.c

    r3897 r3917  
    9898    unsigned int  isCheckedOut : 1;
    9999    unsigned int  isWritable : 1;
     100    unsigned int  closeWhenDone : 1;
    100101    char          filename[MAX_PATH_LENGTH];
    101102    int           fd;
     
    190191
    191192int
    192 tr_fdFileOpen( const char * filename, int write )
     193tr_fdFileCheckout( const char * filename, int write )
    193194{
    194195    int i, winner;
     
    283284    dbgmsg( "checking out '%s' in slot %d", filename, winner );
    284285    o->isCheckedOut = 1;
     286    o->closeWhenDone = 0;
    285287    o->date = tr_date( );
    286288    tr_lockUnlock( gFd->lock );
     
    289291
    290292void
    291 tr_fdFileRelease( int file )
     293tr_fdFileReturn( int fd )
    292294{
    293295    int i;
    294296    tr_lockLock( gFd->lock );
    295297
    296     for( i=0; i<TR_MAX_OPEN_FILES; ++i ) {
     298    for( i=0; i<TR_MAX_OPEN_FILES; ++i )
     299    {
    297300        struct tr_openfile * o = &gFd->open[i];
    298         if( o->fd == file ) {
    299             dbgmsg( "releasing file '%s' in slot #%d", o->filename, i );
    300             /* fsync( o->fd ); */
    301             o->isCheckedOut = 0;
    302             break;
     301        if( o->fd != fd )
     302            continue;
     303
     304        dbgmsg( "releasing file '%s' in slot #%d", o->filename, i );
     305        o->isCheckedOut = 0;
     306        if( o->closeWhenDone )
     307            TrCloseFile( i );
     308       
     309        break;
     310    }
     311   
     312    tr_condSignal( gFd->cond );
     313    tr_lockUnlock( gFd->lock );
     314}
     315
     316void
     317tr_fdFileClose( const char * filename )
     318{
     319    int i;
     320    tr_lockLock( gFd->lock );
     321    dbgmsg( "tr_fdFileClose closing '%s'", filename );
     322
     323    for( i=0; i<TR_MAX_OPEN_FILES; ++i )
     324    {
     325        struct tr_openfile * o = &gFd->open[i];
     326        if( !fileIsOpen(o) || strcmp(filename,o->filename) )
     327            continue;
     328
     329        if( !o->isCheckedOut ) {
     330            dbgmsg( "not checked out, so closing it now... '%s'", filename );
     331            TrCloseFile( i );
     332        } else {
     333            dbgmsg( "flagging file '%s', slot #%d to be closed when checked in", gFd->open[i].filename, i );
     334            o->closeWhenDone = 1;
    303335        }
    304336    }
  • branches/0.9x/libtransmission/fdlimit.h

    r3649 r3917  
    3434void tr_fdClose( void );
    3535
    36 /***********************************************************************
    37  * tr_fdFileOpen
    38  ***********************************************************************
    39  * If it isn't open already, tries to open the file 'name' in the
    40  * directory 'folder'. If 'name' itself contains '/'s, required
    41  * subfolders are created. The file is open read-write if 'write' is 1
    42  * (created if necessary), read-only if 0.
    43  * Returns the file descriptor if successful, otherwise returns
    44  * one of the TR_ERROR_IO_*.
    45  **********************************************************************/
    46 int tr_fdFileOpen( const char * filename, int write );
     36/**
     37 * Returns an fd to the specified filename.
     38 *
     39 * A small repository of open files is kept to avoid the overhead of continually
     40 * opening and closing the same files when writing piece data during download.
     41 * It's also used to ensure that only one client uses the file at a time.
     42 * Clients must check out a file to use it, then return it, like a library, when done.
     43 *
     44 * if write is nonzero and dirname(filename) doesn't exist, dirname is created.
     45 * if write is nonzero and filename doesn't exist, filename is created.
     46 * returns the fd if successful; otherwise, one of TR_ERROR_IO_*
     47 *
     48 * @see tr_fdFileReturn
     49 * @see tr_fdFileClose
     50 */
     51int tr_fdFileCheckout( const char * filename, int write );
    4752
    48 /***********************************************************************
    49  * tr_fdFileRelease
    50  ***********************************************************************
    51  * Indicates that the file whose descriptor is 'file' is unused at the
    52  * moment and can safely be closed.
    53  **********************************************************************/
    54 void tr_fdFileRelease( int file );
     53/**
     54 * Returns an fd from tr_fdFileCheckout() so that other clients may borrow it.
     55 *
     56 * @see tr_fdFileCheckout
     57 * @see tr_fdFileClose
     58 */
     59void tr_fdFileReturn( int file );
     60
     61/**
     62 * Closes a file that's being held by our file repository.
     63 *
     64 * If the file isn't checked out, it's closed immediately.
     65 * If the file is currently checked out, it will be closed upon its return.
     66 *
     67 * @see tr_fdFileCheckout
     68 * @see tr_fdFileReturn
     69 */
     70void tr_fdFileClose( const char * filename );
     71
     72
    5573
    5674/***********************************************************************
  • branches/0.9x/libtransmission/inout.c

    r3897 r3917  
    6767    else if ((ioMode==TR_IO_READ) && stat( path, &sb ) ) /* does file exist? */
    6868        ret = tr_ioErrorFromErrno ();
    69     else if ((fd = tr_fdFileOpen ( path, ioMode==TR_IO_WRITE )) < 0)
     69    else if ((fd = tr_fdFileCheckout ( path, ioMode==TR_IO_WRITE )) < 0)
    7070        ret = fd;
    7171    else if( lseek( fd, (off_t)fileOffset, SEEK_SET ) == ((off_t)-1) )
     
    7777 
    7878    if( fd >= 0 )
    79         tr_fdFileRelease( fd );
     79        tr_fdFileReturn( fd );
    8080
    8181    return ret;
     
    126126    tr_buildPath( path, sizeof(path), tor->destination, file->name, NULL );
    127127
    128     fd = tr_fdFileOpen( path, TRUE );
     128    fd = tr_fdFileCheckout( path, TRUE );
    129129    if( fd < 0 ) /* bad fd */
    130130        ret = fd;
     
    139139
    140140    if( fd >= 0 )
    141         tr_fdFileRelease( fd );
     141        tr_fdFileReturn( fd );
    142142
    143143    return ret;
  • branches/0.9x/libtransmission/peer-msgs.c

    r3897 r3917  
    6969
    7070    PEX_INTERVAL            = (60 * 1000), /* msec between calls to sendPex() */
    71     PEER_PULSE_INTERVAL     = (250),       /* msec between calls to pulse() */
    72     RATE_PULSE_INTERVAL     = (333),       /* msec between calls to ratePulse() */
     71    PEER_PULSE_INTERVAL     = (100),       /* msec between calls to pulse() */
     72    RATE_PULSE_INTERVAL     = (250),       /* msec between calls to ratePulse() */
    7373     
    7474    /* Fast Peers Extension constants */
  • branches/0.9x/libtransmission/torrent.c

    r3905 r3917  
    3434#include "crypto.h" /* for tr_sha1 */
    3535#include "fastresume.h"
     36#include "fdlimit.h" /* tr_fdFileClose */
    3637#include "handshake.h"
    3738#include "inout.h"
     
    10781079stopTorrent( void * vtor )
    10791080{
     1081    int i;
     1082
    10801083    tr_torrent * tor = vtor;
    10811084    tr_ioRecheckRemove( tor );
    10821085    tr_peerMgrStopTorrent( tor->handle->peerMgr, tor->info.hash );
    10831086    tr_trackerStop( tor->tracker );
     1087
     1088    for( i=0; i<tor->info.fileCount; ++i )
     1089    {
     1090        char path[MAX_PATH_LENGTH];
     1091        const tr_file * file = &tor->info.files[i];
     1092        tr_buildPath( path, sizeof(path), tor->destination, file->name, NULL );
     1093        tr_fdFileClose( path );
     1094    }
    10841095}
    10851096
Note: See TracChangeset for help on using the changeset viewer.