This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC PATCH] GETADDRINFO: Make RFC 3484 sorting thread safe.


Hello.

In article <20071017134034.GQ2896@sunsite.mff.cuni.cz> (at Wed, 17 Oct 2007 15:40:34 +0200), Jakub Jelinek <jakub@redhat.com> says:

> On Wed, Oct 17, 2007 at 10:13:53PM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@ wrote:
> > Currently getaddrinfo() is not thread safe due to RFC 3484
> > sorting.  Try making it thread safe by introducing a lock.
> 
> Only if gai.conf is present and contains reload yes, right?
> 
> If so, the locking should be only done in that case IMNSHO.

How about this?

-----------
[PATCH] GETADDRINFO: Make getaddrinfo() thread safe.

We need to block other threads
- until the initialization has been finished
or
- until sorting has been finished if "reload" is set.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>

diff -ru glibc-2.6.1/sysdeps/posix/getaddrinfo.c glibc-2.6.1-ipv6fix/sysdeps/posix/getaddrinfo.c
--- glibc-2.6.1/sysdeps/posix/getaddrinfo.c	2007-04-29 01:09:07.000000000 +0900
+++ glibc-2.6.1-ipv6fix/sysdeps/posix/getaddrinfo.c	2007-10-18 02:44:42.000000000 +0900
@@ -1424,7 +1424,7 @@
 
 /* Nozero if we are supposed to reload the config file automatically
    whenever it changed.  */
-static int gaiconf_reload_flag;
+static int gaiconf_reload_flag = 1;
 
 /* Last modification time.  */
 static struct timespec gaiconf_mtime;
@@ -1482,7 +1482,7 @@
 
 
 static void
-gaiconf_init (void)
+gaiconf_load (int reload)
 {
   struct prefixlist *labellist = NULL;
   size_t nlabellist = 0;
@@ -1721,10 +1721,18 @@
       /* If we previously read the file but it is gone now, free the
 	 old data and use the builtin one.  Leave the reload flag
 	 alone.  */
+      if (!reload)
+	gaiconf_reload_flag = 0;
+
       fini ();
     }
 }
 
+static void
+gaiconf_init (void)
+{
+  gaiconf_load (0);
+}
 
 static void
 gaiconf_reload (void)
@@ -1732,7 +1740,7 @@
   struct stat64 st;
   if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
       || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
-    gaiconf_init ();
+    gaiconf_load (1);
 }
 
 
@@ -1926,6 +1934,21 @@
 
   if (naddrs > 1)
     {
+      /* Lock is not always held; other threads must be blocked
+	 - until the initialization has been finished.
+	 - until sorting has been finished if "reload" is set.
+	 In other words, if "reload" is not set after initialization
+	 has been finished, or after sorting has been finished,
+	 lock is unnecessary. */
+      __libc_lock_define_initialized (static, lock);
+      int locked = 0;
+
+      if (gaiconf_reload_flag)
+	{
+	  __libc_lock_lock (lock);
+	  locked = 1;
+	}
+
       /* Read the config file.  */
       __libc_once_define (static, once);
       __typeof (once) old_once = once;
@@ -1933,6 +1956,14 @@
       if (old_once && gaiconf_reload_flag)
 	gaiconf_reload ();
 
+      /* Release lock if initialization has been finished and
+	 "reload" is not set. */
+      if (!gaiconf_reload_flag && locked)
+	{
+	  __libc_lock_unlock (lock);
+	  locked = 0;
+	}
+
       /* Sort results according to RFC 3484.  */
       struct sort_result results[nresults];
       struct addrinfo *q;
@@ -2017,6 +2048,10 @@
 	 the information.  */
       qsort (results, nresults, sizeof (results[0]), rfc3484_sort);
 
+      /* Release lock if "reload" is set. */
+      if (locked)
+	__libc_lock_unlock (lock);
+
       /* Queue the results up as they come out of sorting.  */
       q = p = results[0].dest_addr;
       for (i = 1; i < nresults; ++i)

-- 
YOSHIFUJI Hideaki @ USAGI Project  <yoshfuji@linux-ipv6.org>
GPG-FP  : 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]