Ignore:
Timestamp:
Jun 24, 2011, 10:39:20 PM (10 years ago)
Author:
jordan
Message:

(trunk libt) #4315 "Transmission 2.31 crashes (segfaults) immediately after launch" -- remove the "max-open-files" code.

max-open-files might have been a nice configuration option once, but (1) we've never advertised it in the gui apps, and (2) the crazy cases are causing more trouble than this feature is worth. It's more complicated now after #4164 -- see #4294, #4311, and this ticket.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/fdlimit.c

    r12397 r12514  
    1010 * $Id$
    1111 */
    12 
    13 #ifndef WIN32
    14  #define HAVE_GETRLIMIT
    15 #endif
    1612
    1713#ifdef HAVE_POSIX_FADVISE
     
    510506}
    511507
    512 static int
    513 fileset_get_size( const struct tr_fileset * set )
    514 {
    515     return set ? set->end - set->begin : 0;
     508/***
     509****
     510****  Startup / Shutdown
     511****
     512***/
     513
     514struct tr_fdInfo
     515{
     516    int peerCount;
     517    struct tr_fileset fileset;
     518};
     519
     520static void
     521ensureSessionFdInfoExists( tr_session * session )
     522{
     523    assert( tr_isSession( session ) );
     524
     525    if( session->fdInfo == NULL )
     526    {
     527        const int TR_MAX_OPEN_FILES = 32;
     528        struct tr_fdInfo * i = tr_new0( struct tr_fdInfo, 1 );
     529        fileset_construct( &i->fileset, TR_MAX_OPEN_FILES );
     530        session->fdInfo = i;
     531    }
     532}
     533
     534void
     535tr_fdClose( tr_session * session )
     536{
     537    if( session && session->fdInfo )
     538    {
     539        struct tr_fdInfo * i = session->fdInfo;
     540        fileset_destruct( &i->fileset );
     541        tr_free( i );
     542        session->fdInfo = NULL;
     543    }
    516544}
    517545
     
    520548***/
    521549
    522 struct tr_fdInfo
    523 {
    524     int socket_count;
    525     int socket_limit;
    526     int public_socket_limit;
    527     struct tr_fileset fileset;
    528 };
    529 
    530550static struct tr_fileset*
    531551get_fileset( tr_session * session )
    532552{
    533     return session && session->fdInfo ? &session->fdInfo->fileset : NULL;
     553    if( !session )
     554        return NULL;
     555
     556    ensureSessionFdInfoExists( session );
     557    return &session->fdInfo->fileset;
    534558}
    535559
     
    636660    int s = -1;
    637661    struct tr_fdInfo * gFd;
    638 
    639662    assert( tr_isSession( session ) );
    640     assert( session->fdInfo != NULL );
    641 
     663
     664    ensureSessionFdInfoExists( session );
    642665    gFd = session->fdInfo;
    643666
    644     if( gFd->socket_count < gFd->socket_limit )
     667    if( gFd->peerCount < session->peerLimit )
    645668        if(( s = socket( domain, type, 0 )) < 0 )
    646669            if( sockerrno != EAFNOSUPPORT )
     
    648671
    649672    if( s > -1 )
    650         ++gFd->socket_count;
    651 
    652     assert( gFd->socket_count >= 0 );
     673        ++gFd->peerCount;
     674
     675    assert( gFd->peerCount >= 0 );
    653676
    654677    if( s >= 0 )
     
    679702
    680703    assert( tr_isSession( s ) );
    681     assert( s->fdInfo != NULL );
    682704    assert( addr );
    683705    assert( port );
    684706
     707    ensureSessionFdInfoExists( s );
    685708    gFd = s->fdInfo;
    686709
     
    690713    if( fd >= 0 )
    691714    {
    692         if( ( gFd->socket_count < gFd->socket_limit )
     715        if( ( gFd->peerCount < s->peerLimit )
    693716            && tr_address_from_sockaddr_storage( addr, port, &sock ) )
    694717        {
    695             ++gFd->socket_count;
     718            ++gFd->peerCount;
    696719        }
    697720        else
     
    717740        {
    718741            tr_netCloseSocket( fd );
    719             --gFd->socket_count;
    720         }
    721 
    722         assert( gFd->socket_count >= 0 );
    723     }
    724 }
    725 
    726 /***
    727 ****
    728 ****  Startup / Shutdown
    729 ****
    730 ***/
    731 
    732 static void
    733 ensureSessionFdInfoExists( tr_session * session )
    734 {
    735     assert( tr_isSession( session ) );
    736 
    737     if( session->fdInfo == NULL )
    738         session->fdInfo = tr_new0( struct tr_fdInfo, 1 );
    739 }
    740 
    741 void
    742 tr_fdClose( tr_session * session )
    743 {
    744     struct tr_fdInfo * gFd = session->fdInfo;
    745 
    746     if( gFd != NULL )
    747     {
    748         fileset_destruct( &gFd->fileset );
    749         tr_free( gFd );
    750     }
    751 
    752     session->fdInfo = NULL;
    753 }
    754 
    755 /***
    756 ****
    757 ***/
    758 
    759 int
    760 tr_fdGetFileLimit( tr_session * session )
    761 {
    762     return fileset_get_size( get_fileset( session ) );
    763 }
    764 
    765 void
    766 tr_fdSetFileLimit( tr_session * session, int limit )
    767 {
    768     int max;
    769 
    770     /* This is a vaguely arbitrary number.
    771        It takes announcer.c's MAX_CONCURRENT_TASKS into account,
    772        plus extra positions for the listening sockets,
    773        plus a few more just to be safe */
    774     const int buffer_slots = 128;
    775 
    776     ensureSessionFdInfoExists( session );
    777 
    778     max = FD_SETSIZE - session->fdInfo->socket_limit - buffer_slots;
    779     if( limit > max )
    780         limit = max;
    781 
    782     if( limit != tr_fdGetFileLimit( session ) )
    783     {
    784         struct tr_fileset * set = get_fileset( session );
    785         fileset_destruct( set );
    786         fileset_construct( set, limit );
    787     }
    788 }
    789 
    790 void
    791 tr_fdSetPeerLimit( tr_session * session, int socket_limit )
    792 {
    793     struct tr_fdInfo * gFd;
    794 
    795     ensureSessionFdInfoExists( session );
    796 
    797     gFd = session->fdInfo;
    798 
    799 #ifdef HAVE_GETRLIMIT
    800     {
    801         struct rlimit rlim;
    802         const int NOFILE_BUFFER = 512;
    803         const int open_max = MIN( FD_SETSIZE, sysconf( _SC_OPEN_MAX ) );
    804         getrlimit( RLIMIT_NOFILE, &rlim );
    805         rlim.rlim_cur = MAX( 1024, open_max );
    806         rlim.rlim_cur = MIN( rlim.rlim_cur, rlim.rlim_max );
    807         setrlimit( RLIMIT_NOFILE, &rlim );
    808         tr_dbg( "setrlimit( RLIMIT_NOFILE, %d ); FD_SETSIZE = %d", (int)rlim.rlim_cur, FD_SETSIZE );
    809         gFd->socket_limit = MIN( socket_limit, (int)rlim.rlim_cur - NOFILE_BUFFER );
    810     }
    811 #else
    812     gFd->socket_limit = socket_limit;
    813 #endif
    814     gFd->public_socket_limit = socket_limit;
    815 
    816     tr_dbg( "socket limit is %d", gFd->socket_limit );
    817 }
    818 
    819 int
    820 tr_fdGetPeerLimit( const tr_session * session )
    821 {
    822     return session && session->fdInfo ? session->fdInfo->public_socket_limit : -1;
    823 }
     742            --gFd->peerCount;
     743        }
     744
     745        assert( gFd->peerCount >= 0 );
     746    }
     747}
Note: See TracChangeset for help on using the changeset viewer.