Dynamically create new threads if necessary.
	* nscd/connections.c (fd_ready): If no thread available for processing
	the request, create a new one unless the limit is reached.
	(start_threads): Check errors from pthread_create.
	* nscd/nscd.h: Declare max_nthreads.
	* nscd/nscd_conf.c: Parse max-nthreads entry.
	* nscd/nscd.conf: Add max-threads entry.
	* nscd/nscd_stat.c: Print current and maximum number of threads.
This commit is contained in:
Ulrich Drepper 2004-10-03 21:11:37 +00:00
parent 4401d75905
commit 27e8285643
6 changed files with 64 additions and 18 deletions

View file

@ -1,5 +1,14 @@
2004-10-03 Ulrich Drepper <drepper@redhat.com>
Dynamically create new threads if necessary.
* nscd/connections.c (fd_ready): If no thread available for processing
the request, create a new one unless the limit is reached.
(start_threads): Check errors from pthread_create.
* nscd/nscd.h: Declare max_nthreads.
* nscd/nscd_conf.c: Parse max-nthreads entry.
* nscd/nscd.conf: Add max-threads entry.
* nscd/nscd_stat.c: Print current and maximum number of threads.
Implement paranoia mode.
* nscd/connections.c (nscd_init): Mark database and socket descriptors
as close on exec.

View file

@ -69,6 +69,8 @@ static gid_t *server_groups;
#endif
static int server_ngroups;
static pthread_attr_t attr;
static void begin_drop_privileges (void);
static void finish_drop_privileges (void);
@ -167,8 +169,10 @@ static struct database_dyn *const serv2db[LASTREQ] =
#define CACHE_PRUNE_INTERVAL 15
/* Number of threads to use. */
/* Initial number of threads to use. */
int nthreads = -1;
/* Maximum number of threads to use. */
int max_nthreads = 32;
/* Socket for incoming connections. */
static int sock;
@ -1206,6 +1210,19 @@ fd_ready (int fd)
{
++client_queued;
do_signal = false;
/* Try to start another thread to help out. */
pthread_t th;
if (nthreads < max_nthreads
&& pthread_create (&th, &attr, nscd_run,
(void *) (long int) nthreads) == 0)
{
/* We got another thread. */
++nthreads;
/* The new thread might new a kick. */
do_signal = true;
}
}
pthread_mutex_unlock (&readylist_lock);
@ -1452,21 +1469,29 @@ start_threads (void)
/* Create the attribute for the threads. They are all created
detached. */
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
/* Use 1MB stacks, twice as much for 64-bit architectures. */
pthread_attr_setstacksize (&attr, 1024 * 1024 * (sizeof (void *) / 4));
/* We allow less than LASTDB threads only for debugging. */
if (debug_level == 0)
nthreads = MAX (nthreads, lastdb);
int nfailed = 0;
for (long int i = 0; i < nthreads; ++i)
{
pthread_t th;
pthread_create (&th, &attr, nscd_run, (void *) i);
if (pthread_create (&th, &attr, nscd_run, (void *) (i - nfailed)) != 0)
++nfailed;
}
if (nthreads - nfailed < lastdb)
{
/* We could not start enough threads. */
dbg_log (_("could only start %d threads; terminating"),
nthreads - nfailed);
exit (1);
}
pthread_attr_destroy (&attr);
/* Determine how much room for descriptors we should initially
allocate. This might need to change later if we cap the number

View file

@ -7,7 +7,8 @@
#
# logfile <file>
# debug-level <level>
# threads <#threads to use>
# threads <initial #threads to use>
# max-threads <maximum #threads to use>
# server-user <user to run server as instead of root>
# server-user is ignored if nscd is started with -S parameters
# stat-user <user who is allowed to request statistics>
@ -29,6 +30,7 @@
# logfile /var/log/nscd.log
# threads 6
# max-threads 128
# server-user nobody
# stat-user somebody
debug-level 0

View file

@ -102,8 +102,10 @@ extern const struct iovec grp_iov_disabled;
extern const struct iovec hst_iov_disabled;
/* Number of threads to run. */
/* Initial number of threads to run. */
extern int nthreads;
/* Maximum number of threads to use. */
extern int max_nthreads;
/* Tables for which we cache data with uid. */
extern int secure_in_use; /* Is one of the above 1? */

View file

@ -184,6 +184,10 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
if (nthreads == -1)
nthreads = MAX (atol (arg1), lastdb);
}
else if (strcmp (entry, "max-threads") == 0)
{
max_nthreads = MAX (atol (arg1), lastdb);
}
else if (strcmp (entry, "server-user") == 0)
{
if (!arg1)
@ -282,6 +286,10 @@ cannot get current working directory: %s; disabling paranoia mode"),
}
}
/* Enforce sanity. */
if (max_nthreads < nthreads)
max_nthreads = nthreads;
/* Free the buffer. */
free (line);
/* Close configuration file. */

View file

@ -143,8 +143,8 @@ receive_print_stats (void)
int fd;
int i;
uid_t uid = getuid ();
const char *yesstr = _(" yes");
const char *nostr = _(" no");
const char *yesstr = nl_langinfo (YESSTR);
const char *nostr = nl_langinfo (NOSTR);
/* Find out whether there is another user but root allowed to
request statistics. */
@ -225,22 +225,22 @@ receive_print_stats (void)
else
printf (_(" %2lus server runtime\n"), diff);
printf (_("%15lu number of times clients had to wait\n"
printf (_("%15d current number of threads\n"
"%15d maximum number of threads\n"
"%15lu number of times clients had to wait\n"
"%15s paranoia mode enabled\n"
"%15lu restart internal\n"),
data.client_queued, paranoia ? yesstr : nostr,
(unsigned long int) restart_interval);
nthreads, max_nthreads, data.client_queued,
paranoia ? yesstr : nostr, (unsigned long int) restart_interval);
for (i = 0; i < lastdb; ++i)
{
unsigned long int hit = data.dbs[i].poshit + data.dbs[i].neghit;
unsigned long int all = hit + data.dbs[i].posmiss + data.dbs[i].negmiss;
const char *enabled = nl_langinfo (data.dbs[i].enabled ? YESSTR : NOSTR);
const char *check_file = nl_langinfo (data.dbs[i].check_file
? YESSTR : NOSTR);
const char *shared = nl_langinfo (data.dbs[i].shared ? YESSTR : NOSTR);
const char *persistent = nl_langinfo (data.dbs[i].persistent
? YESSTR : NOSTR);
const char *enabled = data.dbs[i].enabled ? yesstr : nostr;
const char *check_file = data.dbs[i].check_file ? yesstr : nostr;
const char *shared = data.dbs[i].shared ? yesstr : nostr;
const char *persistent = data.dbs[i].persistent ? yesstr : nostr;
if (enabled[0] == '\0')
/* The locale does not provide this information so we have to