pthread_rwlock_wrlock (&table->lock);
if (__builtin_expect (pthread_rwlock_trywrlock (&table->lock) != 0, 0)) { ++table->wrlockdelayed; pthread_rwlock_wrlock (&table->lock); }
prune_cache (struct database *table, time_t now){  size_t cnt = table->module;  int mark[cnt];  int anything = 0;  size_t first = cnt + 1;  size_t last = 0;  /* If this table is not actually used don't do anything.  */  if (cnt == 0)    return;  /* If we check for the modification of the underlying file we invalidate     the entries also in this case.  */  if (table->check_file)    {      struct stat st;      if (stat (table->filename, &st) < 0)	{	  char buf[128];	  /* We cannot stat() the file, disable file checking if the             file does not exist.  */	  dbg_log (_("cannot stat() file `%s': %s"),		   table->filename, strerror_r (errno, buf, sizeof (buf)));	  if (errno == ENOENT)	    table->check_file = 0;	}      else	{	  if (st.st_mtime != table->file_mtime)	    {	      /* The file changed.  Invalidate all entries.  */	      now = LONG_MAX;	      table->file_mtime = st.st_mtime;	    }	}    }  /* We run through the table and find values which are not valid anymore.   Note that for the initial step, finding the entries to be removed,   we don't need to get any lock.  It is at all timed assured that the   linked lists are set up correctly and that no second thread prunes   the cache.  */  do    {      struct hashentry *runp = table->array[--cnt];      mark[cnt] = 0;      while (runp != NULL)	{	  if (runp->timeout < now)	    {	      ++mark[cnt];	      anything = 1;	      first = MIN (first, cnt);	      last = MAX (last, cnt);	    }	  runp = runp->next;	}    }  while (cnt > 0);  if (anything)    {      struct hashentry *head = NULL;      /* Now we have to get the write lock since we are about to modify	 the table.  */      pthread_rwlock_wrlock (&table->lock);      while (first <= last)	{	  if (mark[first] > 0)	    {	      struct hashentry *runp;	      while (table->array[first]->timeout < now)		{		  table->array[first]->dellist = head;		  head = table->array[first];		  table->array[first] = head->next;		  if (--mark[first] == 0)		    break;		}	      runp = table->array[first];	      while (mark[first] > 0)		{		  if (runp->next->timeout < now)		    {		      runp->next->dellist = head;		      head = runp->next;		      runp->next = head->next;		      --mark[first];		    }		  else		    runp = runp->next;		}	    }	  ++first;	}      /* It's all done.  */      pthread_rwlock_unlock (&table->lock);      /* And another run to free the data.  */      do	{	  struct hashentry *old = head;	  if (debug_level > 0)	    {	      char buf[INET6_ADDRSTRLEN];	      const char *str;	      if ((old->type == GETHOSTBYADDR || old->type == GETHOSTBYADDRv6)		  && (old->last || old->data == (void *) -1))		{		  inet_ntop (old->type == GETHOSTBYADDR ? AF_INET : AF_INET6,			     old->key, buf, sizeof (buf));		  str = buf;		}	      else		str = old->last ? old->key : (old->data == (void *) -1					      ? old->key : "???");	      dbg_log ("remove %s entry \"%s\"", serv2str[old->type], str);	    }	  /* Free the data structures.  */	  if (old->data == (void *) -1)	    free (old->key);	  else if (old->last)	    free (old->data);	  head = head->dellist;	  free (old);	}      while (head != NULL);    }}