Changeset 12514


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.

Location:
trunk/libtransmission
Files:
5 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}
  • trunk/libtransmission/fdlimit.h

    r12397 r12514  
    2222 * @{
    2323 */
    24 
    25 void tr_fdSetFileLimit( tr_session * session, int limit );
    26 
    27 int tr_fdGetFileLimit( tr_session * session );
    28 
    29 void tr_fdSetGlobalPeerLimit( tr_session * session, int limit );
    3024
    3125/***
     
    126120void     tr_fdClose( tr_session * session );
    127121
    128 
    129 void     tr_fdSetPeerLimit( tr_session * session, int n );
    130 
    131 int      tr_fdGetPeerLimit( const tr_session * );
    132 
    133122/* @} */
  • trunk/libtransmission/session.c

    r12508 r12514  
    320320    tr_bencDictAddBool( d, TR_PREFS_KEY_INCOMPLETE_DIR_ENABLED,   false );
    321321    tr_bencDictAddInt ( d, TR_PREFS_KEY_MSGLEVEL,                 TR_MSG_INF );
    322     tr_bencDictAddInt ( d, TR_PREFS_KEY_OPEN_FILE_LIMIT,          atoi( TR_DEFAULT_OPEN_FILE_LIMIT_STR ) );
    323322    tr_bencDictAddInt ( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL,        atoi( TR_DEFAULT_PEER_LIMIT_GLOBAL_STR ) );
    324323    tr_bencDictAddInt ( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT,       atoi( TR_DEFAULT_PEER_LIMIT_TORRENT_STR ) );
     
    384383    tr_bencDictAddBool( d, TR_PREFS_KEY_INCOMPLETE_DIR_ENABLED,   tr_sessionIsIncompleteDirEnabled( s ) );
    385384    tr_bencDictAddInt ( d, TR_PREFS_KEY_MSGLEVEL,                 tr_getMessageLevel( ) );
    386     tr_bencDictAddInt ( d, TR_PREFS_KEY_OPEN_FILE_LIMIT,          tr_fdGetFileLimit( s ) );
    387     tr_bencDictAddInt ( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL,        tr_sessionGetPeerLimit( s ) );
     385    tr_bencDictAddInt ( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL,        s->peerLimit );
    388386    tr_bencDictAddInt ( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT,       s->peerLimitPerTorrent );
    389387    tr_bencDictAddInt ( d, TR_PREFS_KEY_PEER_PORT,                tr_sessionGetPeerPort( s ) );
     
    830828        tr_sessionSetPortForwardingEnabled( session, boolVal );
    831829
    832     /* file and peer socket limits */
    833830    if( tr_bencDictFindInt( settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &i ) )
    834         tr_fdSetPeerLimit( session, i );
    835     if( tr_bencDictFindInt( settings, TR_PREFS_KEY_OPEN_FILE_LIMIT, &i ) )
    836         tr_fdSetFileLimit( session, i );
     831        session->peerLimit = i;
    837832
    838833    /**
     
    15851580
    15861581void
    1587 tr_sessionSetPeerLimit( tr_session * session, uint16_t maxGlobalPeers )
    1588 {
    1589     assert( tr_isSession( session ) );
    1590 
    1591     tr_fdSetPeerLimit( session, maxGlobalPeers );
     1582tr_sessionSetPeerLimit( tr_session * session, uint16_t n )
     1583{
     1584    assert( tr_isSession( session ) );
     1585
     1586    session->peerLimit = n;
    15921587}
    15931588
     
    15971592    assert( tr_isSession( session ) );
    15981593
    1599     return tr_fdGetPeerLimit( session );
     1594    return session->peerLimit;
    16001595}
    16011596
  • trunk/libtransmission/session.h

    r12461 r12514  
    130130    struct tr_event_handle     * events;
    131131
     132    uint16_t                     peerLimit;
    132133    uint16_t                     peerLimitPerTorrent;
    133134
  • trunk/libtransmission/transmission.h

    r12281 r12514  
    149149#define TR_DEFAULT_BIND_ADDRESS_IPV4        "0.0.0.0"
    150150#define TR_DEFAULT_BIND_ADDRESS_IPV6             "::"
    151 #define TR_DEFAULT_OPEN_FILE_LIMIT_STR           "32"
    152151#define TR_DEFAULT_RPC_WHITELIST          "127.0.0.1"
    153152#define TR_DEFAULT_RPC_PORT_STR                "9091"
     
    181180#define TR_PREFS_KEY_INCOMPLETE_DIR_ENABLED       "incomplete-dir-enabled"
    182181#define TR_PREFS_KEY_MSGLEVEL                     "message-level"
    183 #define TR_PREFS_KEY_OPEN_FILE_LIMIT              "open-file-limit"
    184182#define TR_PREFS_KEY_PEER_LIMIT_GLOBAL            "peer-limit-global"
    185183#define TR_PREFS_KEY_PEER_LIMIT_TORRENT           "peer-limit-per-torrent"
Note: See TracChangeset for help on using the changeset viewer.