(trunk libT) make the default number of open files 32 rather than 16, and make it configurable via settings.json. (Reported by Lucius Windschuh via denis_)

This commit is contained in:
Charles Kerr 2009-01-08 19:20:24 +00:00
parent f3db4c14b7
commit 55aa6d834f
5 changed files with 49 additions and 42 deletions

View File

@ -33,7 +33,7 @@
#include <stdlib.h>
#include <string.h>
#ifdef SYS_DARWIN
#include <fcntl.h>
#include <fcntl.h>
#endif
#ifdef HAVE_FALLOCATE
@ -71,8 +71,6 @@
enum
{
TR_MAX_OPEN_FILES = 16, /* real files, not sockets */
NOFILE_BUFFER = 512, /* the process' number of open files is
globalMaxPeers + NOFILE_BUFFER */
};
@ -90,9 +88,12 @@ struct tr_openfile
struct tr_fd_s
{
int socketCount;
int socketMax;
tr_lock * lock;
struct tr_openfile open[TR_MAX_OPEN_FILES];
int socketLimit;
struct tr_openfile * openFiles;
int openFileLimit;
tr_lock * lock;
};
static struct tr_fd_s * gFd = NULL;
@ -104,7 +105,7 @@ static struct tr_fd_s * gFd = NULL;
***/
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#define O_LARGEFILE 0
#endif
static int
@ -176,7 +177,7 @@ TrOpenFile( int i,
int doPreallocate,
uint64_t desiredFileSize )
{
struct tr_openfile * file = &gFd->open[i];
struct tr_openfile * file = &gFd->openFiles[i];
int flags;
char * filename;
struct stat sb;
@ -236,10 +237,10 @@ fileIsOpen( const struct tr_openfile * o )
static void
TrCloseFile( int i )
{
struct tr_openfile * o = &gFd->open[i];
struct tr_openfile * o = &gFd->openFiles[i];
assert( i >= 0 );
assert( i < TR_MAX_OPEN_FILES );
assert( i < gFd->openFileLimit );
assert( fileIsOpen( o ) );
close( o->fd );
@ -275,9 +276,9 @@ tr_fdFileCheckout( const char * folder,
tr_lockLock( gFd->lock );
/* Is it already open? */
for( i = 0; i < TR_MAX_OPEN_FILES; ++i )
for( i = 0; i < gFd->openFileLimit; ++i )
{
o = &gFd->open[i];
o = &gFd->openFiles[i];
if( !fileIsOpen( o ) )
continue;
@ -315,9 +316,9 @@ tr_fdFileCheckout( const char * folder,
uint64_t date = tr_date( ) + 1;
/* look for the file that's been open longest */
for( i = 0; i < TR_MAX_OPEN_FILES; ++i )
for( i = 0; i < gFd->openFileLimit; ++i )
{
o = &gFd->open[i];
o = &gFd->openFiles[i];
if( !fileIsOpen( o ) )
{
@ -335,10 +336,10 @@ tr_fdFileCheckout( const char * folder,
if( winner >= 0 )
{
if( fileIsOpen( &gFd->open[winner] ) )
if( fileIsOpen( &gFd->openFiles[winner] ) )
{
dbgmsg( "closing file '%s', slot #%d",
gFd->open[winner].filename,
gFd->openFiles[winner].filename,
winner );
TrCloseFile( winner );
}
@ -354,7 +355,7 @@ tr_fdFileCheckout( const char * folder,
}
assert( winner >= 0 );
o = &gFd->open[winner];
o = &gFd->openFiles[winner];
if( !fileIsOpen( o ) )
{
const int err = TrOpenFile( winner, folder, torrentFile, doWrite, doPreallocate, desiredFileSize );
@ -385,9 +386,9 @@ tr_fdFileReturn( int fd )
tr_lockLock( gFd->lock );
for( i = 0; i < TR_MAX_OPEN_FILES; ++i )
for( i = 0; i < gFd->openFileLimit; ++i )
{
struct tr_openfile * o = &gFd->open[i];
struct tr_openfile * o = &gFd->openFiles[i];
if( o->fd != fd )
continue;
@ -409,9 +410,9 @@ tr_fdFileClose( const char * filename )
tr_lockLock( gFd->lock );
for( i = 0; i < TR_MAX_OPEN_FILES; ++i )
for( i = 0; i < gFd->openFileLimit; ++i )
{
struct tr_openfile * o = &gFd->open[i];
struct tr_openfile * o = &gFd->openFiles[i];
if( !fileIsOpen( o ) || strcmp( filename, o->filename ) )
continue;
@ -426,7 +427,7 @@ tr_fdFileClose( const char * filename )
{
dbgmsg(
"flagging file '%s', slot #%d to be closed when checked in",
gFd->open[i].filename, i );
gFd->openFiles[i].filename, i );
o->closeWhenDone = 1;
}
}
@ -443,7 +444,7 @@ tr_fdFileClose( const char * filename )
static int
getSocketMax( struct tr_fd_s * gFd )
{
return gFd->socketMax;
return gFd->socketLimit;
}
int
@ -545,12 +546,14 @@ tr_fdSocketClose( int s )
***/
void
tr_fdInit( int globalPeerLimit )
tr_fdInit( size_t openFileLimit, size_t socketLimit )
{
int i;
assert( gFd == NULL );
gFd = tr_new0( struct tr_fd_s, 1 );
gFd->openFiles = tr_new0( struct tr_openfile, openFileLimit );
gFd->openFileLimit = openFileLimit;
gFd->lock = tr_lockNew( );
#ifdef HAVE_GETRLIMIT
@ -558,18 +561,18 @@ tr_fdInit( int globalPeerLimit )
struct rlimit rlim;
getrlimit( RLIMIT_NOFILE, &rlim );
rlim.rlim_cur = MIN( rlim.rlim_max,
(rlim_t)( globalPeerLimit + NOFILE_BUFFER ) );
(rlim_t)( socketLimit + NOFILE_BUFFER ) );
setrlimit( RLIMIT_NOFILE, &rlim );
gFd->socketMax = rlim.rlim_cur - NOFILE_BUFFER;
gFd->socketLimit = rlim.rlim_cur - NOFILE_BUFFER;
tr_dbg( "setrlimit( RLIMIT_NOFILE, %d )", (int)rlim.rlim_cur );
}
#else
gFd->socketMax = globalPeerLimit;
gFd->socketLimit = socketLimit;
#endif
tr_dbg( "%d usable file descriptors", globalPeerLimit );
tr_dbg( "%zu usable file descriptors", socketLimit );
for( i = 0; i < TR_MAX_OPEN_FILES; ++i )
gFd->open[i].fd = -1;
for( i = 0; i < gFd->openFileLimit; ++i )
gFd->openFiles[i].fd = -1;
}
void
@ -577,8 +580,8 @@ tr_fdClose( void )
{
int i = 0;
for( i = 0; i < TR_MAX_OPEN_FILES; ++i )
if( fileIsOpen( &gFd->open[i] ) )
for( i = 0; i < gFd->openFileLimit; ++i )
if( fileIsOpen( &gFd->openFiles[i] ) )
TrCloseFile( i );
tr_lockFree( gFd->lock );
@ -591,12 +594,12 @@ void
tr_fdSetPeerLimit( uint16_t n )
{
assert( gFd != NULL && "tr_fdInit() must be called first!" );
gFd->socketMax = n;
gFd->socketLimit = n;
}
uint16_t
tr_fdGetPeerLimit( void )
{
return gFd ? gFd->socketMax : -1;
return gFd ? gFd->socketLimit : -1;
}

View File

@ -28,12 +28,8 @@
#include "net.h"
/***********************************************************************
* tr_fdInit
***********************************************************************
* Detect the maximum number of open files and initializes things.
**********************************************************************/
void tr_fdInit( int globalPeerLimit );
void tr_fdInit( size_t openFileLimit,
size_t globalPeerLimit );
/**
* Returns an fd to the specified filename.

View File

@ -227,6 +227,7 @@ tr_sessionGetDefaultSettings( tr_benc * d )
tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, TR_DEFAULT_ENCRYPTION );
tr_bencDictAddInt( d, TR_PREFS_KEY_LAZY_BITFIELD, TRUE );
tr_bencDictAddInt( d, TR_PREFS_KEY_MSGLEVEL, TR_MSG_INF );
tr_bencDictAddInt( d, TR_PREFS_KEY_OPEN_FILE_LIMIT, atoi( TR_DEFAULT_OPEN_FILE_LIMIT_STR ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, atoi( TR_DEFAULT_PEER_LIMIT_GLOBAL_STR ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT, atoi( TR_DEFAULT_PEER_LIMIT_TORRENT_STR ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, atoi( TR_DEFAULT_PEER_PORT_STR ) );
@ -270,6 +271,7 @@ tr_sessionGetSettings( tr_session * s, struct tr_benc * d )
tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, s->encryptionMode );
tr_bencDictAddInt( d, TR_PREFS_KEY_LAZY_BITFIELD, s->useLazyBitfield );
tr_bencDictAddInt( d, TR_PREFS_KEY_MSGLEVEL, tr_getMessageLevel( ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_OPEN_FILE_LIMIT, s->openFileLimit );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, tr_sessionGetPeerLimit( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT, s->peerLimitPerTorrent );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( s ) );
@ -458,9 +460,12 @@ tr_sessionInit( const char * tag,
/* Initialize rate and file descripts controls */
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &i );
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_OPEN_FILE_LIMIT, &i );
assert( found );
tr_fdInit( i );
session->openFileLimit = i;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &j );
assert( found );
tr_fdInit( session->openFileLimit, j );
/**
*** random port

View File

@ -74,6 +74,7 @@ struct tr_session
struct tr_event_handle * events;
uint16_t peerLimitPerTorrent;
uint16_t openFileLimit;
tr_port peerPort;
tr_port randomPortLow;

View File

@ -114,6 +114,7 @@ typedef enum
}
tr_encryption_mode;
#define TR_DEFAULT_OPEN_FILE_LIMIT_STR "32"
#define TR_DEFAULT_RPC_WHITELIST "127.0.0.1"
#define TR_DEFAULT_RPC_PORT_STR "9091"
#define TR_DEFAULT_PEER_PORT_STR "51413"
@ -128,6 +129,7 @@ tr_encryption_mode;
#define TR_PREFS_KEY_ENCRYPTION "encryption"
#define TR_PREFS_KEY_LAZY_BITFIELD "lazy-bitfield-enabled"
#define TR_PREFS_KEY_MSGLEVEL "message-level"
#define TR_PREFS_KEY_OPEN_FILE_LIMIT "open-file-limit"
#define TR_PREFS_KEY_PEER_LIMIT_GLOBAL "peer-limit-global"
#define TR_PREFS_KEY_PEER_LIMIT_TORRENT "peer-limit-per-torrent"
#define TR_PREFS_KEY_PEER_PORT "peer-port"