(struct database_dyn): Add propagate field.
[kopensolaris-gnu/glibc.git] / nscd / nscd_helper.c
index ed7c863..1dfe746 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
+#include <time.h>
 #include <unistd.h>
 #include <sys/mman.h>
 #include <sys/poll.h>
@@ -175,35 +176,40 @@ get_mapping (request_type type, const char *key,
   struct mapped_database *result = NO_MAPPING;
 #ifdef SCM_RIGHTS
   const size_t keylen = strlen (key) + 1;
-  char resdata[keylen];
   int saved_errno = errno;
 
   int mapfd = -1;
 
   /* Send the request.  */
-  struct iovec iov[2];
-  request_header req;
+  struct
+  {
+    request_header req;
+    char key[keylen];
+  } reqdata;
 
   int sock = open_socket ();
   if (sock < 0)
     goto out;
 
-  req.version = NSCD_VERSION;
-  req.type = type;
-  req.key_len = keylen;
-
-  iov[0].iov_base = &req;
-  iov[0].iov_len = sizeof (req);
-  iov[1].iov_base = (void *) key;
-  iov[1].iov_len = keylen;
-
-  if (TEMP_FAILURE_RETRY (__writev (sock, iov, 2))
-      != iov[0].iov_len + iov[1].iov_len)
+  reqdata.req.version = NSCD_VERSION;
+  reqdata.req.type = type;
+  reqdata.req.key_len = keylen;
+  memcpy (reqdata.key, key, keylen);
+
+# ifndef MSG_NOSIGNAL
+#  define MSG_NOSIGNAL 0
+# endif
+  if (__builtin_expect (TEMP_FAILURE_RETRY (__send (sock, &reqdata,
+                                                   sizeof (reqdata),
+                                                   MSG_NOSIGNAL))
+                       != sizeof (reqdata), 0))
     /* We cannot even write the request.  */
     goto out_close2;
 
   /* Room for the data sent along with the file descriptor.  We expect
      the key name back.  */
+# define resdata reqdata.key
+  struct iovec iov[1];
   iov[0].iov_base = resdata;
   iov[0].iov_len = keylen;
 
@@ -230,44 +236,46 @@ get_mapping (request_type type, const char *key,
   if (wait_on_socket (sock) <= 0)
     goto out_close2;
 
-#ifndef MSG_NOSIGNAL
-# define MSG_NOSIGNAL 0
-#endif
-  if (TEMP_FAILURE_RETRY (__recvmsg (sock, &msg, MSG_NOSIGNAL)) != keylen)
+  if (__builtin_expect (TEMP_FAILURE_RETRY (__recvmsg (sock, &msg, 0))
+                       != keylen, 0))
     goto out_close2;
 
   mapfd = *(int *) CMSG_DATA (cmsg);
 
-  if (CMSG_FIRSTHDR (&msg)->cmsg_len != CMSG_LEN (sizeof (int)))
+  if (__builtin_expect (CMSG_FIRSTHDR (&msg)->cmsg_len
+                       != CMSG_LEN (sizeof (int)), 0))
     goto out_close;
 
   struct stat64 st;
-  if (strcmp (resdata, key) != 0
-      || fstat64 (mapfd, &st) != 0
-      || st.st_size < sizeof (struct database_pers_head))
+  if (__builtin_expect (strcmp (resdata, key) != 0, 0)
+      || __builtin_expect (fstat64 (mapfd, &st) != 0, 0)
+      || __builtin_expect (st.st_size < sizeof (struct database_pers_head), 0))
     goto out_close;
 
   struct database_pers_head head;
-  if (TEMP_FAILURE_RETRY (__pread (mapfd, &head, sizeof (head), 0))
-      != sizeof (head))
+  if (__builtin_expect (TEMP_FAILURE_RETRY (__pread (mapfd, &head,
+                                                    sizeof (head), 0))
+                       != sizeof (head), 0))
     goto out_close;
 
-  if (head.version != DB_VERSION || head.header_size != sizeof (head)
+  if (__builtin_expect (head.version != DB_VERSION, 0)
+      || __builtin_expect (head.header_size != sizeof (head), 0)
       /* This really should not happen but who knows, maybe the update
         thread got stuck.  */
-      || (! head.nscd_certainly_running
-         && head.timestamp + MAPPING_TIMEOUT < time (NULL)))
+      || __builtin_expect (! head.nscd_certainly_running
+                          && head.timestamp + MAPPING_TIMEOUT < time (NULL),
+                          0))
     goto out_close;
 
   size_t size = (sizeof (head) + roundup (head.module * sizeof (ref_t), ALIGN)
                 + head.data_size);
 
-  if (st.st_size < size)
+  if (__builtin_expect (st.st_size < size, 0))
     goto out_close;
 
   /* The file is large enough, map it now.  */
   void *mapping = __mmap (NULL, size, PROT_READ, MAP_SHARED, mapfd, 0);
-  if (mapping != MAP_FAILED)
+  if (__builtin_expect (mapping != MAP_FAILED, 1))
     {
       /* Allocate a record for the mapping.  */
       struct mapped_database *newp = malloc (sizeof (*newp));
@@ -308,17 +316,18 @@ get_mapping (request_type type, const char *key,
 
 struct mapped_database *
 __nscd_get_map_ref (request_type type, const char *name,
-                   struct locked_map_ptr *mapptr, int *gc_cyclep)
+                   volatile struct locked_map_ptr *mapptr, int *gc_cyclep)
 {
   struct mapped_database *cur = mapptr->mapped;
   if (cur == NO_MAPPING)
     return cur;
 
   int cnt = 0;
-  while (atomic_compare_and_exchange_val_acq (&mapptr->lock, 1, 0) != 0)
+  while (__builtin_expect (atomic_compare_and_exchange_val_acq (&mapptr->lock,
+                                                               1, 0) != 0, 0))
     {
       // XXX Best number of rounds?
-      if (++cnt > 5)
+      if (__builtin_expect (++cnt > 5, 0))
        return NO_MAPPING;
 
       atomic_delay ();
@@ -332,7 +341,8 @@ __nscd_get_map_ref (request_type type, const char *name,
       if (cur == NULL
          || (cur->head->nscd_certainly_running == 0
              && cur->head->timestamp + MAPPING_TIMEOUT < time (NULL)))
-       cur = get_mapping (type, name, &mapptr->mapped);
+       cur = get_mapping (type, name,
+                          (struct mapped_database **) &mapptr->mapped);
 
       if (__builtin_expect (cur != NO_MAPPING, 1))
        {