Ignore:
Timestamp:
Oct 23, 2009, 3:41:36 AM (12 years ago)
Author:
charles
Message:

(trunk) trunk's just been too stable lately. #2119: reload settings.json on SIGHUP

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/fdlimit.c

    r9346 r9387  
    6464#include "net.h"
    6565#include "platform.h" /* MAX_PATH_LENGTH, TR_PATH_DELIMITER */
     66#include "session.h"
     67#include "torrent.h" /* tr_isTorrent() */
    6668#include "utils.h"
    6769
     
    9294};
    9395
    94 struct tr_fd_s
     96struct tr_fdInfo
    9597{
    9698    int                   socketCount;
    9799    int                   socketLimit;
     100    int                   publicSocketLimit;
    98101    int                   openFileLimit;
    99102    struct tr_openfile  * openFiles;
    100103};
    101 
    102 static struct tr_fd_s * gFd = NULL;
    103104
    104105/***
     
    278279 */
    279280static int
    280 TrOpenFile( int                      i,
     281TrOpenFile( tr_session             * session,
     282            int                      i,
    281283            const char             * filename,
    282284            tr_bool                  doWrite,
     
    284286            uint64_t                 desiredFileSize )
    285287{
    286     struct tr_openfile * file = &gFd->openFiles[i];
    287     int                  flags;
    288     struct stat          sb;
    289     tr_bool              alreadyExisted;
     288    int flags;
     289    struct stat sb;
     290    tr_bool alreadyExisted;
     291    struct tr_openfile * file;
     292
     293    assert( tr_isSession( session ) );
     294    assert( session->fdInfo != NULL );
     295
     296    file = &session->fdInfo->openFiles[i];
    290297
    291298    /* create subfolders, if any */
     
    371378
    372379int
    373 tr_fdFileGetCached( int              torrentId,
    374                     tr_file_index_t  fileNum,
    375                     tr_bool          doWrite )
     380tr_fdFileGetCached( tr_session       * session,
     381                    int                torrentId,
     382                    tr_file_index_t    fileNum,
     383                    tr_bool            doWrite )
    376384{
    377385    struct tr_openfile * match = NULL;
    378 
     386    struct tr_fdInfo * gFd;
     387
     388    assert( tr_isSession( session ) );
     389    assert( session->fdInfo != NULL );
    379390    assert( torrentId > 0 );
    380391    assert( tr_isBool( doWrite ) );
     392
     393    gFd = session->fdInfo;
    381394
    382395    /* is it already open? */
     
    411424/* returns an fd on success, or a -1 on failure and sets errno */
    412425int
    413 tr_fdFileCheckout( int                      torrentId,
     426tr_fdFileCheckout( tr_session             * session,
     427                   int                      torrentId,
    414428                   tr_file_index_t          fileNum,
    415429                   const char             * filename,
     
    419433{
    420434    int i, winner = -1;
     435    struct tr_fdInfo * gFd;
    421436    struct tr_openfile * o;
    422437
     438    assert( tr_isSession( session ) );
     439    assert( session->fdInfo != NULL );
    423440    assert( torrentId > 0 );
    424441    assert( filename && *filename );
    425442    assert( tr_isBool( doWrite ) );
     443
     444    gFd = session->fdInfo;
    426445
    427446    dbgmsg( "looking for file '%s', writable %c", filename, doWrite ? 'y' : 'n' );
     
    488507    if( !fileIsOpen( o ) )
    489508    {
    490         const int err = TrOpenFile( winner, filename, doWrite,
     509        const int err = TrOpenFile( session, winner, filename, doWrite,
    491510                                    preallocationMode, desiredFileSize );
    492511        if( err ) {
     
    509528
    510529void
    511 tr_fdFileClose( const tr_torrent * tor, tr_file_index_t fileNum )
     530tr_fdFileClose( tr_session        * session,
     531                const tr_torrent  * tor,
     532                tr_file_index_t     fileNum )
    512533{
    513534    struct tr_openfile * o;
     535    struct tr_fdInfo * gFd;
    514536    const struct tr_openfile * end;
    515537    const int torrentId = tr_torrentId( tor );
     538
     539    assert( tr_isSession( session ) );
     540    assert( session->fdInfo != NULL );
     541    assert( tr_isTorrent( tor ) );
     542    assert( fileNum < tor->info.fileCount );
     543
     544    gFd = session->fdInfo;
     545
    516546    for( o=gFd->openFiles, end=o+gFd->openFileLimit; o!=end; ++o )
    517547    {
     
    529559
    530560void
    531 tr_fdTorrentClose( int torrentId )
     561tr_fdTorrentClose( tr_session * session, int torrentId )
    532562{
    533563    struct tr_openfile * o;
     564    struct tr_fdInfo * gFd;
    534565    const struct tr_openfile * end;
     566
     567    assert( tr_isSession( session ) );
     568    assert( session->fdInfo != NULL );
     569
     570    gFd = session->fdInfo;
    535571
    536572    for( o=gFd->openFiles, end=o+gFd->openFileLimit; o!=end; ++o )
     
    545581***/
    546582
    547 static TR_INLINE int
    548 getSocketMax( struct tr_fd_s * gFd )
    549 {
    550     return gFd->socketLimit;
    551 }
    552 
    553583int
    554 tr_fdSocketCreate( int domain, int type )
     584tr_fdSocketCreate( tr_session * session, int domain, int type )
    555585{
    556586    int s = -1;
    557 
    558     if( gFd->socketCount < getSocketMax( gFd ) )
     587    struct tr_fdInfo * gFd;
     588
     589    assert( tr_isSession( session ) );
     590    assert( session->fdInfo != NULL );
     591
     592    gFd = session->fdInfo;
     593
     594    if( gFd->socketCount < gFd->socketLimit )
    559595        if( ( s = socket( domain, type, 0 ) ) < 0 )
    560596        {
     
    568604
    569605    assert( gFd->socketCount >= 0 );
    570 
    571606    return s;
    572607}
    573608
    574609int
    575 tr_fdSocketAccept( int           b,
     610tr_fdSocketAccept( tr_session  * session,
     611                   int           b,
    576612                   tr_address  * addr,
    577613                   tr_port     * port )
     
    579615    int s;
    580616    unsigned int len;
     617    struct tr_fdInfo * gFd;
    581618    struct sockaddr_storage sock;
    582619
     620    assert( tr_isSession( session ) );
     621    assert( session->fdInfo != NULL );
    583622    assert( addr );
    584623    assert( port );
    585624
     625    gFd = session->fdInfo;
     626
    586627    len = sizeof( struct sockaddr_storage );
    587628    s = accept( b, (struct sockaddr *) &sock, &len );
    588629
    589     if( ( s >= 0 ) && gFd->socketCount > getSocketMax( gFd ) )
     630    if( ( s >= 0 ) && gFd->socketCount > gFd->socketLimit )
    590631    {
    591632        EVUTIL_CLOSESOCKET( s );
     
    624665
    625666void
    626 tr_fdSocketClose( int fd )
    627 {
     667tr_fdSocketClose( tr_session * session, int fd )
     668{
     669    struct tr_fdInfo * gFd;
     670
     671    assert( tr_isSession( session ) );
     672    assert( session->fdInfo != NULL );
     673
     674    gFd = session->fdInfo;
     675
    628676    if( fd >= 0 )
    629677    {
     
    641689***/
    642690
     691static void
     692ensureSessionFdInfoExists( tr_session * session )
     693{
     694    assert( tr_isSession( session ) );
     695
     696    if( session->fdInfo == NULL )
     697        session->fdInfo = tr_new0( struct tr_fdInfo, 1 );
     698}
     699
    643700void
    644 tr_fdInit( size_t openFileLimit, size_t socketLimit )
    645 {
    646     int i;
    647 
    648     assert( gFd == NULL );
    649     gFd = tr_new0( struct tr_fd_s, 1 );
    650     gFd->openFiles = tr_new0( struct tr_openfile, openFileLimit );
    651     gFd->openFileLimit = openFileLimit;
     701tr_fdClose( tr_session * session )
     702{
     703    struct tr_fdInfo * gFd;
     704    struct tr_openfile * o;
     705    const struct tr_openfile * end;
     706
     707    assert( tr_isSession( session ) );
     708    assert( session->fdInfo != NULL );
     709
     710    gFd = session->fdInfo;
     711
     712    for( o=gFd->openFiles, end=o+gFd->openFileLimit; o!=end; ++o )
     713        if( fileIsOpen( o ) )
     714            TrCloseFile( o );
     715
     716    tr_free( gFd->openFiles );
     717    tr_free( gFd );
     718    session->fdInfo = NULL;
     719}
     720
     721/***
     722****
     723***/
     724
     725void
     726tr_fdSetFileLimit( tr_session * session, int limit )
     727{
     728    struct tr_fdInfo * gFd;
     729
     730    ensureSessionFdInfoExists( session );
     731
     732    gFd = session->fdInfo;
     733
     734    if( gFd->openFileLimit != limit )
     735    {
     736        int i;
     737        struct tr_openfile * o;
     738        const struct tr_openfile * end;
     739
     740        /* close any files we've got open  */
     741        for( o=gFd->openFiles, end=o+gFd->openFileLimit; o!=end; ++o )
     742            if( fileIsOpen( o ) )
     743                TrCloseFile( o );
     744
     745        /* rebuild the openFiles array */
     746        tr_free( gFd->openFiles );
     747        gFd->openFiles = tr_new0( struct tr_openfile, limit );
     748        gFd->openFileLimit = limit;
     749        for( i=0; i<gFd->openFileLimit; ++i )
     750            gFd->openFiles[i].fd = -1;
     751    }
     752}
     753
     754int
     755tr_fdGetFileLimit( const tr_session * session )
     756{
     757    return session && session->fdInfo ? session->fdInfo->openFileLimit : -1;
     758}
     759
     760void
     761tr_fdSetPeerLimit( tr_session * session, int limit )
     762{
     763    struct tr_fdInfo * gFd;
     764
     765    ensureSessionFdInfoExists( session );
     766
     767    gFd = session->fdInfo;
    652768
    653769#ifdef HAVE_GETRLIMIT
     
    655771        struct rlimit rlim;
    656772        getrlimit( RLIMIT_NOFILE, &rlim );
    657         rlim.rlim_cur = MIN( rlim.rlim_max,
    658                             (rlim_t)( socketLimit + NOFILE_BUFFER ) );
     773        rlim.rlim_cur = MIN( rlim.rlim_max, (rlim_t)( limit + NOFILE_BUFFER ) );
    659774        setrlimit( RLIMIT_NOFILE, &rlim );
    660775        gFd->socketLimit = rlim.rlim_cur - NOFILE_BUFFER;
     
    662777    }
    663778#else
    664     gFd->socketLimit = socketLimit;
    665 #endif
    666     tr_dbg( "%zu usable file descriptors", socketLimit );
    667 
    668     for( i = 0; i < gFd->openFileLimit; ++i )
    669         gFd->openFiles[i].fd = -1;
    670 }
    671 
    672 void
    673 tr_fdClose( void )
    674 {
    675     struct tr_openfile * o;
    676     const struct tr_openfile * end;
    677 
    678     for( o=gFd->openFiles, end=o+gFd->openFileLimit; o!=end; ++o )
    679         if( fileIsOpen( o ) )
    680             TrCloseFile( o );
    681 
    682     tr_free( gFd->openFiles );
    683     tr_free( gFd );
    684     gFd = NULL;
    685 }
    686 
    687 void
    688 tr_fdSetPeerLimit( uint16_t n )
    689 {
    690     assert( gFd != NULL && "tr_fdInit() must be called first!" );
    691     gFd->socketLimit = n;
    692 }
    693 
    694 uint16_t
    695 tr_fdGetPeerLimit( void )
    696 {
    697     return gFd ? gFd->socketLimit : -1;
    698 }
     779    gFd->socketLimit = limit;
     780#endif
     781    gFd->publicSocketLimit = limit;
     782
     783    tr_dbg( "%d usable file descriptors", limit );
     784}
     785
     786int
     787tr_fdGetPeerLimit( const tr_session * session )
     788{
     789    return session && session->fdInfo ? session->fdInfo->publicSocketLimit : -1;
     790}
Note: See TracChangeset for help on using the changeset viewer.