[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r4100 - in /fsf/trunk/libc: ./ elf/ nptl/ nptl/sysdeps/unix/sysv/linux/ nptl/sysdeps/unix/sysv/linux/sh/ nscd/ sysdeps/unix/...



Author: eglibc
Date: Tue Nov  6 00:03:31 2007
New Revision: 4100

Log:
Import glibc-mainline for 2007-11-06

Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/elf/rtld.c
    fsf/trunk/libc/nptl/ChangeLog
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/register-atfork.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
    fsf/trunk/libc/nscd/aicache.c
    fsf/trunk/libc/nscd/cache.c
    fsf/trunk/libc/nscd/connections.c
    fsf/trunk/libc/nscd/nscd.conf
    fsf/trunk/libc/nscd/nscd.h
    fsf/trunk/libc/nscd/nscd_setup_thread.c
    fsf/trunk/libc/sysdeps/unix/sysv/linux/nscd_setup_thread.c
    fsf/trunk/libc/time/tzfile.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Tue Nov  6 00:03:31 2007
@@ -1,8 +1,48 @@
+2007-11-05  Daniel Jacobowitz  <dan@xxxxxxxxxxxxxxxx>
+
+	* elf/rtld.c (dl_main): Use the page size to find the map start.
+
+2007-11-05  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* time/tzfile.c (__tzfile_read): Fix check for version 0 data files.
+	Patch by Szymon Siwek <sls@xxxxxxxxxxxx>.
+
+	* nscd/aicache.c (addhstaiX): Check herrno after IPv4 lookup only
+	when the lookup call failed.
+
+	* nscd/nscd.h (struct database_dyn): Rename prunelock to prune_lock.
+	Add prune_cond and wakeup_time.
+	(CACHE_PRUNE_INTERNAL): Define.
+	Update declarations of prune_cache and setup_thread.
+	* nscd/connections.c (dbs): Update initializers.
+	(CACHE_PRUNE_INTERNAL): Moved to nscd.h.
+	(nscd_init): Default number of threads is now 4.
+	(invalidate_cache): Take lock before calling prune_cache.
+	(handle_request): If SELinux forbids the request, say so.
+	(readylist_cond): Use static initializer.
+	(nscd_run_prune): New function.  Used only by pruning threads.
+	(nscd_run_worder): Renamed from nscd_run.  Remove support for pruning
+	here.
+	(fd_ready): Update nscd_run reference.
+	(start_threads): No need to initialize readylist_cond.
+	Start pruning threads separately.
+	* nscd/nscd_setup_thread.c: Change return value type to int and always
+	return 0.
+	* sysdeps/unix/sysv/linux/nscd_setup_thread.c: Change return value type
+	to int and return nonzero value if we can use the TID address hack.
+	* nscd/cache.c (cache_add): If next wakeup time of cleanup thread for
+	the database is later than the new entry's timeout, update the
+	wakeup time and wake the cleanup thread.
+	(prune_cache): Return seconds the next entry in the database is still
+	valid.  Remove locking for pruning here.
+	* nscd/nscd.conf: Document default number of threads.
+
 2007-10-31  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Make sure
 	stack is properly aligned for the target function.
 	Correct unwind info.
+
 	* elf/rtld.c (dl_main): Initialize stack and pointer guard early
 	when using auditing libraries.
 

Modified: fsf/trunk/libc/elf/rtld.c
==============================================================================
--- fsf/trunk/libc/elf/rtld.c (original)
+++ fsf/trunk/libc/elf/rtld.c Tue Nov  6 00:03:31 2007
@@ -1166,7 +1166,8 @@
 	  ElfW(Addr) allocend;
 
 	  /* Remember where the main program starts in memory.  */
-	  mapstart = (main_map->l_addr + (ph->p_vaddr & ~(ph->p_align - 1)));
+	  mapstart = (main_map->l_addr
+		      + (ph->p_vaddr & ~(GLRO(dl_pagesize) - 1)));
 	  if (main_map->l_map_start > mapstart)
 	    main_map->l_map_start = mapstart;
 

Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Tue Nov  6 00:03:31 2007
@@ -1,3 +1,15 @@
+2007-11-05  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/register-atfork.c (__register_atfork):
+	Use __linkin_atfork.
+
+2007-11-03  Mike Frysinger  <vapier@xxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S (LOAD_FUTEX_WAIT): Add
+	missing line continuations.
+	* sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S (LOAD_FUTEX_WAIT,
+	LOAD_FUTEX_WAKE): Likewise.  Also add missing 3rd parameter.
+
 2007-10-28  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	[BZ #5220]

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/register-atfork.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/register-atfork.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/register-atfork.c Tue Nov  6 00:03:31 2007
@@ -98,8 +98,7 @@
       newp->child_handler = child;
       newp->dso_handle = dso_handle;
 
-      newp->next = __fork_handlers;
-      __fork_handlers = newp;
+      __linkin_atfork (newp);
     }
 
   /* Release the lock.  */

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S Tue Nov  6 00:03:31 2007
@@ -76,7 +76,7 @@
 	add	tmp2, tmp 	; \
 	mov.l	@tmp, tmp2	; \
 	bra	98f		; \
-	 mov	#FUTEX_PRIVATE_FLAG, tmp
+	 mov	#FUTEX_PRIVATE_FLAG, tmp ; \
 99:	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
 98:	extu.b	tmp, tmp	; \
 	xor	tmp, reg	; \
@@ -88,7 +88,7 @@
 	add	tmp2, tmp 	; \
 	mov.l	@tmp, tmp2	; \
 	bra	98f		; \
-	 mov	#FUTEX_PRIVATE_FLAG, tmp
+	 mov	#FUTEX_PRIVATE_FLAG, tmp ; \
 99:	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
 98:	extu.b	tmp, tmp	; \
 	xor	tmp, reg	; \
@@ -96,13 +96,13 @@
 	mov	#FUTEX_WAIT, tmp ; \
 	or	tmp, reg
 # endif
-# define LOAD_FUTEX_WAKE(reg,tmp) \
+# define LOAD_FUTEX_WAKE(reg,tmp,tmp2) \
 	stc	gbr, tmp	; \
 	mov.w	99f, tmp2	; \
 	add	tmp2, tmp 	; \
 	mov.l	@tmp, tmp2	; \
 	bra	98f		; \
-	 mov	#FUTEX_PRIVATE_FLAG, tmp
+	 mov	#FUTEX_PRIVATE_FLAG, tmp ; \
 99:	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
 98:	extu.b	tmp, tmp	; \
 	xor	tmp, reg	; \

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S Tue Nov  6 00:03:31 2007
@@ -42,7 +42,7 @@
 	add	tmp2, tmp 	; \
 	mov.l	@tmp, tmp2	; \
 	bra	98f		; \
-	 mov	#FUTEX_PRIVATE_FLAG, tmp
+	 mov	#FUTEX_PRIVATE_FLAG, tmp ; \
 99:	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
 98:	extu.b	tmp, tmp	; \
 	xor	tmp, reg	; \
@@ -54,7 +54,7 @@
 	add	tmp2, tmp 	; \
 	mov.l	@tmp, tmp2	; \
 	bra	98f		; \
-	 mov	#FUTEX_PRIVATE_FLAG, tmp
+	 mov	#FUTEX_PRIVATE_FLAG, tmp ; \
 99:	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
 98:	extu.b	tmp, tmp	; \
 	xor	tmp, reg	; \

Modified: fsf/trunk/libc/nscd/aicache.c
==============================================================================
--- fsf/trunk/libc/nscd/aicache.c (original)
+++ fsf/trunk/libc/nscd/aicache.c Tue Nov  6 00:03:31 2007
@@ -157,7 +157,7 @@
 	      tmpbuf4 = tmpbuf6;
 	    }
 
-	  /* Next collect IPv4 information first.  */
+	  /* Next collect IPv4 information.  */
 	  while (1)
 	    {
 	      rc4 = 0;
@@ -170,7 +170,7 @@
 	      tmpbuf4 = extend_alloca (tmpbuf4, tmpbuf4len, 2 * tmpbuf4len);
 	    }
 
-	  if (rc4 != 0 || herrno == NETDB_INTERNAL)
+	  if (rc4 != 0 && herrno == NETDB_INTERNAL)
 	    goto out;
 
 	  if (status[0] == NSS_STATUS_SUCCESS

Modified: fsf/trunk/libc/nscd/cache.c
==============================================================================
--- fsf/trunk/libc/nscd/cache.c (original)
+++ fsf/trunk/libc/nscd/cache.c Tue Nov  6 00:03:31 2007
@@ -197,6 +197,20 @@
 	   (char *) &table->head->array[hash] - (char *) table->head
 	   + sizeof (ref_t), MS_ASYNC);
 
+  /* Perhaps the prune thread for the data is not running in a long
+     time.  Wake it if necessary.  */
+  time_t next_wakeup = table->wakeup_time;
+  while (next_wakeup + CACHE_PRUNE_INTERVAL > packet->timeout)
+    if (atomic_compare_and_exchange_bool_acq (&table->wakeup_time,
+					      packet->timeout,
+					      next_wakeup) == 0)
+      {
+	pthread_cond_signal (&table->prune_cond);
+	break;
+      }
+    else
+      next_wakeup = table->wakeup_time;
+
   return 0;
 }
 
@@ -212,7 +226,7 @@
    actually remove them.  This is complicated by the way we have to
    free the data structures since some hash table entries share the same
    data.  */
-void
+time_t
 prune_cache (struct database_dyn *table, time_t now, int fd)
 {
   size_t cnt = table->head->module;
@@ -226,7 +240,9 @@
 	  int32_t resp = 0;
 	  writeall (fd, &resp, sizeof (resp));
 	}
-      return;
+
+      /* No need to do this again anytime soon.  */
+      return 24 * 60 * 60;
     }
 
   /* If we check for the modification of the underlying file we invalidate
@@ -254,21 +270,6 @@
 	      table->file_mtime = st.st_mtime;
 	    }
 	}
-    }
-
-  /* This function can be called from the cleanup thread but also in
-     response to an invalidate command.  Make sure only one thread is
-     running.  When not serving INVALIDATE request, no need for the
-     second thread to wait around.  */
-  if (__builtin_expect (pthread_mutex_trylock (&table->prunelock) != 0, 0))
-    {
-      /* The work is already being done.  */
-      if (fd == -1)
-	return;
-
-      /* We have to wait until the thread is done and then run again
-	 so that the large NOW value invalidates all entries.  */
-      pthread_mutex_lock (&table->prunelock);
     }
 
   /* We run through the table and find values which are not valid anymore.
@@ -473,5 +474,5 @@
   if (any)
     gc (table);
 
-  pthread_mutex_unlock (&table->prunelock);
+  return next_timeout - now;
 }

Modified: fsf/trunk/libc/nscd/connections.c
==============================================================================
--- fsf/trunk/libc/nscd/connections.c (original)
+++ fsf/trunk/libc/nscd/connections.c Tue Nov  6 00:03:31 2007
@@ -104,7 +104,7 @@
 {
   [pwddb] = {
     .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
-    .prunelock = PTHREAD_MUTEX_INITIALIZER,
+    .prune_lock = PTHREAD_MUTEX_INITIALIZER,
     .enabled = 0,
     .check_file = 1,
     .persistent = 0,
@@ -123,7 +123,7 @@
   },
   [grpdb] = {
     .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
-    .prunelock = PTHREAD_MUTEX_INITIALIZER,
+    .prune_lock = PTHREAD_MUTEX_INITIALIZER,
     .enabled = 0,
     .check_file = 1,
     .persistent = 0,
@@ -142,7 +142,7 @@
   },
   [hstdb] = {
     .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
-    .prunelock = PTHREAD_MUTEX_INITIALIZER,
+    .prune_lock = PTHREAD_MUTEX_INITIALIZER,
     .enabled = 0,
     .check_file = 1,
     .persistent = 0,
@@ -161,7 +161,7 @@
   },
   [servdb] = {
     .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
-    .prunelock = PTHREAD_MUTEX_INITIALIZER,
+    .prune_lock = PTHREAD_MUTEX_INITIALIZER,
     .enabled = 0,
     .check_file = 1,
     .persistent = 0,
@@ -210,10 +210,6 @@
 };
 
 
-/* Number of seconds between two cache pruning runs.  */
-#define CACHE_PRUNE_INTERVAL	15
-
-
 /* Initial number of threads to use.  */
 int nthreads = -1;
 /* Maximum number of threads to use.  */
@@ -495,7 +491,7 @@
 
   if (nthreads == -1)
     /* No configuration for this value, assume a default.  */
-    nthreads = 2 * lastdb;
+    nthreads = 4;
 
   for (size_t cnt = 0; cnt < lastdb; ++cnt)
     if (dbs[cnt].enabled)
@@ -898,7 +894,11 @@
     }
 
   if (dbs[number].enabled)
-    prune_cache (&dbs[number], LONG_MAX, fd);
+    {
+      pthread_mutex_lock (&dbs[number].prune_lock);
+      prune_cache (&dbs[number], LONG_MAX, fd);
+      pthread_mutex_unlock (&dbs[number].prune_lock);
+    }
   else
     {
       resp = 0;
@@ -970,9 +970,13 @@
       return;
     }
 
-  /* Make the SELinux check before we go on to the standard checks.  */
+  /* Perform the SELinux check before we go on to the standard checks.  */
   if (selinux_enabled && nscd_request_avc_has_perm (fd, req->type) != 0)
-    return;
+    {
+      if (debug_level > 0)
+	dbg_log (_("request not handled due to missing permission"));
+      return;
+    }
 
   struct database_dyn *db = reqinfo[req->type].db;
 
@@ -1336,7 +1340,7 @@
 /* Conditional variable and mutex to signal availability of entries in
    READYLIST.  The condvar is initialized dynamically since we might
    use a different clock depending on availability.  */
-static pthread_cond_t readylist_cond;
+static pthread_cond_t readylist_cond = PTHREAD_COND_INITIALIZER;
 static pthread_mutex_t readylist_lock = PTHREAD_MUTEX_INITIALIZER;
 
 /* The clock to use with the condvar.  */
@@ -1346,32 +1350,76 @@
 static unsigned long int nready;
 
 
-/* This is the main loop.  It is replicated in different threads but the
-   `poll' call makes sure only one thread handles an incoming connection.  */
+/* Function for the clean-up threads.  */
 static void *
 __attribute__ ((__noreturn__))
-nscd_run (void *p)
+nscd_run_prune (void *p)
 {
   const long int my_number = (long int) p;
-  const int run_prune = my_number < lastdb && dbs[my_number].enabled;
+  assert (dbs[my_number].enabled);
+
+  int dont_need_update = setup_thread (&dbs[my_number]);
+
+  /* We are running.  */
+  dbs[my_number].head->timestamp = time (NULL);
+
   struct timespec prune_ts;
-  int to = 0;
-  char buf[256];
-
-  if (run_prune)
-    {
-      setup_thread (&dbs[my_number]);
-
-      /* We are running.  */
-      dbs[my_number].head->timestamp = time (NULL);
+  if (clock_gettime (timeout_clock, &prune_ts) == -1)
+    /* Should never happen.  */
+    abort ();
+
+  /* Compute the initial timeout time.  Prevent all the timers to go
+     off at the same time by adding a db-based value.  */
+  prune_ts.tv_sec += CACHE_PRUNE_INTERVAL + my_number;
+
+  pthread_mutex_lock (&dbs[my_number].prune_lock);
+  while (1)
+    {
+      /* Wait, but not forever.  */
+      int e = pthread_cond_timedwait (&dbs[my_number].prune_cond,
+				      &dbs[my_number].prune_lock,
+				      &prune_ts);
+      assert (e == 0 || e == ETIMEDOUT);
+
+      time_t next_wait;
+      time_t now = time (NULL);
+      if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time)
+	{
+	  next_wait = prune_cache (&dbs[my_number], now, -1);
+	  next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL);
+	  /* If clients cannot determine for sure whether nscd is running
+	     we need to wake up occasionally to update the timestamp.
+	     Wait 90% of the update period.  */
+#define UPDATE_MAPPING_TIMEOUT (MAPPING_TIMEOUT * 9 / 10)
+	  if (__builtin_expect (! dont_need_update, 0))
+	    next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait);
+
+	  /* Make it known when we will wake up again.  */
+	  dbs[my_number].wakeup_time = now + next_wait;
+	}
+      else
+	/* The cache was just pruned.  Do not do it again now.  Just
+	   use the new timeout value.  */
+	next_wait = dbs[my_number].wakeup_time - now;
 
       if (clock_gettime (timeout_clock, &prune_ts) == -1)
 	/* Should never happen.  */
 	abort ();
 
-      /* Compute timeout time.  */
-      prune_ts.tv_sec += CACHE_PRUNE_INTERVAL;
-    }
+      /* Compute next timeout time.  */
+      prune_ts.tv_sec += next_wait;
+    }
+}
+
+
+/* This is the main loop.  It is replicated in different threads but
+   the the use of the ready list makes sure only one thread handles an
+   incoming connection.  */
+static void *
+__attribute__ ((__noreturn__))
+nscd_run_worker (void *p)
+{
+  char buf[256];
 
   /* Initial locking.  */
   pthread_mutex_lock (&readylist_lock);
@@ -1382,26 +1430,7 @@
   while (1)
     {
       while (readylist == NULL)
-	{
-	  if (run_prune)
-	    {
-	      /* Wait, but not forever.  */
-	      to = pthread_cond_timedwait (&readylist_cond, &readylist_lock,
-					   &prune_ts);
-
-	      /* If we were woken and there is no work to be done,
-		 just start pruning.  */
-	      if (readylist == NULL && to == ETIMEDOUT)
-		{
-		  --nready;
-		  pthread_mutex_unlock (&readylist_lock);
-		  goto only_prune;
-		}
-	    }
-	  else
-	    /* No need to timeout.  */
-	    pthread_cond_wait (&readylist_cond, &readylist_lock);
-	}
+	pthread_cond_wait (&readylist_cond, &readylist_lock);
 
       struct fdlist *it = readylist->next;
       if (readylist->next == readylist)
@@ -1504,28 +1533,6 @@
       /* We are done.  */
       close (fd);
 
-      /* Check whether we should be pruning the cache. */
-      assert (run_prune || to == 0);
-      if (to == ETIMEDOUT)
-	{
-	only_prune:
-	  /* The pthread_cond_timedwait() call timed out.  It is time
-		 to clean up the cache.  */
-	  assert (my_number < lastdb);
-	  prune_cache (&dbs[my_number], time (NULL), -1);
-
-	  if (clock_gettime (timeout_clock, &prune_ts) == -1)
-	    /* Should never happen.  */
-	    abort ();
-
-	  /* Compute next timeout time.  */
-	  prune_ts.tv_sec += CACHE_PRUNE_INTERVAL;
-
-	  /* In case the list is emtpy we do not want to run the prune
-	     code right away again.  */
-	  to = 0;
-	}
-
       /* Re-locking.  */
       pthread_mutex_lock (&readylist_lock);
 
@@ -1568,7 +1575,7 @@
       /* Try to start another thread to help out.  */
       pthread_t th;
       if (nthreads < max_nthreads
-	  && pthread_create (&th, &attr, nscd_run,
+	  && pthread_create (&th, &attr, nscd_run_worker,
 			     (void *) (long int) nthreads) == 0)
 	{
 	  /* We got another thread.  */
@@ -1828,10 +1835,6 @@
 	timeout_clock = CLOCK_MONOTONIC;
 #endif
 
-  pthread_cond_init (&readylist_cond, &condattr);
-  pthread_condattr_destroy (&condattr);
-
-
   /* Create the attribute for the threads.  They are all created
      detached.  */
   pthread_attr_init (&attr);
@@ -1843,19 +1846,46 @@
   if (debug_level == 0)
     nthreads = MAX (nthreads, lastdb);
 
-  int nfailed = 0;
+  /* Create the threads which prune the databases.  */
+  // XXX Ideally this work would be done by some of the worker threads.
+  // XXX But this is problematic since we would need to be able to wake
+  // XXX them up explicitly as well as part of the group handling the
+  // XXX ready-list.  This requires an operation where we can wait on
+  // XXX two conditional variables at the same time.  This operation
+  // XXX does not exist (yet).
+  for (long int i = 0; i < lastdb; ++i)
+    {
+      /* Initialize the conditional variable.  */
+      if (pthread_cond_init (&dbs[i].prune_cond, &condattr) != 0)
+	{
+	  dbg_log (_("could not initialize conditional variable"));
+	  exit (1);
+	}
+
+      pthread_t th;
+      if (dbs[i].enabled
+	  && pthread_create (&th, &attr, nscd_run_prune, (void *) i) != 0)
+	{
+	  dbg_log (_("could not start clean-up thread; terminating"));
+	  exit (1);
+	}
+    }
+
+  pthread_condattr_destroy (&condattr);
+
   for (long int i = 0; i < nthreads; ++i)
     {
       pthread_t th;
-      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);
+      if (pthread_create (&th, &attr, nscd_run_worker, NULL) != 0)
+	{
+	  if (i == 0)
+	    {
+	      dbg_log (_("could not start any worker thread; terminating"));
+	      exit (1);
+	    }
+
+	  break;
+	}
     }
 
   /* Determine how much room for descriptors we should initially

Modified: fsf/trunk/libc/nscd/nscd.conf
==============================================================================
--- fsf/trunk/libc/nscd/nscd.conf (original)
+++ fsf/trunk/libc/nscd/nscd.conf Tue Nov  6 00:03:31 2007
@@ -31,8 +31,8 @@
 
 
 #	logfile			/var/log/nscd.log
-#	threads			6
-#	max-threads		128
+#	threads			4
+#	max-threads		32
 #	server-user		nobody
 #	stat-user		somebody
 	debug-level		0

Modified: fsf/trunk/libc/nscd/nscd.h
==============================================================================
--- fsf/trunk/libc/nscd/nscd.h (original)
+++ fsf/trunk/libc/nscd/nscd.h Tue Nov  6 00:03:31 2007
@@ -59,7 +59,9 @@
 struct database_dyn
 {
   pthread_rwlock_t lock;
-  pthread_mutex_t prunelock;
+  pthread_cond_t prune_cond;
+  pthread_mutex_t prune_lock;
+  time_t wakeup_time;
 
   int enabled;
   int check_file;
@@ -111,6 +113,11 @@
 #define DEFAULT_DATASIZE_PER_BUCKET 1024
 
 
+/* Number of seconds between two cache pruning runs if we do not have
+   better information when it is really needed.  */
+#define CACHE_PRUNE_INTERVAL	15
+
+
 /* Global variables.  */
 extern struct database_dyn dbs[lastdb];
 extern const char *const dbnames[lastdb];
@@ -189,7 +196,7 @@
 extern int cache_add (int type, const void *key, size_t len,
 		      struct datahead *packet, bool first,
 		      struct database_dyn *table, uid_t owner);
-extern void prune_cache (struct database_dyn *table, time_t now, int fd);
+extern time_t prune_cache (struct database_dyn *table, time_t now, int fd);
 
 /* pwdcache.c */
 extern void addpwbyname (struct database_dyn *db, int fd, request_header *req,
@@ -258,7 +265,7 @@
 
 
 /* nscd_setup_thread.c */
-extern void setup_thread (struct database_dyn *db);
+extern int setup_thread (struct database_dyn *db);
 
 
 /* Special version of TEMP_FAILURE_RETRY for functions returning error

Modified: fsf/trunk/libc/nscd/nscd_setup_thread.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_setup_thread.c (original)
+++ fsf/trunk/libc/nscd/nscd_setup_thread.c Tue Nov  6 00:03:31 2007
@@ -20,8 +20,9 @@
 #include <nscd.h>
 
 
-void
+int
 setup_thread (struct database_dyn *db)
 {
   /* Nothing.  */
+  return 0;
 }

Modified: fsf/trunk/libc/sysdeps/unix/sysv/linux/nscd_setup_thread.c
==============================================================================
--- fsf/trunk/libc/sysdeps/unix/sysv/linux/nscd_setup_thread.c (original)
+++ fsf/trunk/libc/sysdeps/unix/sysv/linux/nscd_setup_thread.c Tue Nov  6 00:03:31 2007
@@ -23,7 +23,7 @@
 #include <sysdep.h>
 
 
-void
+int
 setup_thread (struct database_dyn *db)
 {
 #ifdef __NR_set_tid_address
@@ -43,6 +43,8 @@
     /* We know the kernel can reset this field when nscd terminates.
        So, set the field to a nonzero value which indicates that nscd
        is certainly running and clients can skip the test.  */
-    db->head->nscd_certainly_running = 1;
+    return db->head->nscd_certainly_running = 1;
 #endif
+
+  return 0;
 }

Modified: fsf/trunk/libc/time/tzfile.c
==============================================================================
--- fsf/trunk/libc/time/tzfile.c (original)
+++ fsf/trunk/libc/time/tzfile.c Tue Nov  6 00:03:31 2007
@@ -381,7 +381,7 @@
       else
 	tzspec[tzspec_len - 1] = '\0';
     }
-  else if (sizeof (time_t) == 4 && tzhead.tzh_version != '\0')
+  else if (sizeof (time_t) == 4 && tzhead.tzh_version[0] != '\0')
     {
       /* Get the TZ string.  */
       if (__builtin_expect (fread_unlocked ((void *) &tzhead, sizeof (tzhead),