This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [RFC PATCH] GETADDRINFO: Make RFC 3484 sorting thread safe.
- From: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji at linux-ipv6 dot org>
- To: jakub at redhat dot com
- Cc: drepper at redhat dot com, libc-alpha at sources dot redhat dot com, usagi-core at linux-ipv6 dot org, yoshfuji at linux-ipv6 dot org
- Date: Thu, 18 Oct 2007 02:48:31 +0900 (JST)
- Subject: Re: [RFC PATCH] GETADDRINFO: Make RFC 3484 sorting thread safe.
- References: <20071017.221353.77648074.yoshfuji@linux-ipv6.org> <20071017134034.GQ2896@sunsite.mff.cuni.cz>
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