Hello! Needed on glibc-2_5-branch and HEAD. Reported at <http://savannah.gnu.org/bugs/?18217> and finally on <http://sourceware.org/bugzilla/show_bug.cgi?id=3748>, where it was rejected by Ulrich Drepper. Roland wanted to have a look.
2006-12-18 Thomas Schwinge <[EMAIL PROTECTED]> * bits/libc-lock.h (__libc_once_else): New definiton. * sysdeps/mach/bits/libc-lock.h: Likewise. * sysdeps/mach/hurd/bits/libc-lock.h: Likewise. * nptl/sysdeps/pthread/bits/libc-lock.h: Likewise. * sysdeps/posix/getaddrinfo.c (getaddrinfo): Use __libc_once_else and a new local function instead of using implementational details. Index: sysdeps/posix/getaddrinfo.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/posix/getaddrinfo.c,v retrieving revision 1.107 diff -u -p -r1.107 getaddrinfo.c --- sysdeps/posix/getaddrinfo.c 2 Oct 2006 16:49:47 -0000 1.107 +++ sysdeps/posix/getaddrinfo.c 18 Dec 2006 14:12:19 -0000 @@ -2031,11 +2031,13 @@ getaddrinfo (const char *name, const cha if (naddrs > 1) { /* Read the config file. */ + void _gaiconf_reload (void) + { + if (gaiconf_reload_flag) + gaiconf_reload (); + } __libc_once_define (static, once); - __typeof (once) old_once = once; - __libc_once (once, gaiconf_init); - if (old_once && gaiconf_reload_flag) - gaiconf_reload (); + __libc_once_else (once, gaiconf_init, _gaiconf_reload); /* Sort results according to RFC 3484. */ struct sort_result results[nresults]; Index: bits/libc-lock.h =================================================================== RCS file: /cvs/glibc/libc/bits/libc-lock.h,v retrieving revision 1.11 diff -u -p -r1.11 libc-lock.h --- bits/libc-lock.h 25 Aug 2003 09:07:41 -0000 1.11 +++ bits/libc-lock.h 18 Dec 2006 14:12:19 -0000 @@ -89,7 +90,7 @@ /* Define once control variable. */ #define __libc_once_define(CLASS, NAME) CLASS int NAME = 0 -/* Call handler iff the first call. */ +/* Call INIT_FUNCTION iff the first call. */ #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \ do { \ if ((ONCE_CONTROL) == 0) { \ @@ -98,6 +99,15 @@ } \ } while (0) +/* Call INIT_FUNCTION iff the first call. Otherwise call ELSE_FUNCTION. */ +#define __libc_once_else(ONCE_CONTROL, INIT_FUNCTION, ELSE_FUNCTION) \ + do { \ + if ((ONCE_CONTROL) == 1) \ + (ELSE_FUNCTION) (); \ + else \ + __libc_once (ONCE_CONTROL, INIT_FUNCTION); \ + } while (0) + /* Start a critical region with a cleanup function */ #define __libc_cleanup_region_start(DOIT, FCT, ARG) \ Index: sysdeps/mach/bits/libc-lock.h =================================================================== RCS file: /cvs/glibc/libc/sysdeps/mach/bits/libc-lock.h,v retrieving revision 1.10 diff -u -p -r1.10 libc-lock.h --- sysdeps/mach/bits/libc-lock.h 6 Dec 2002 11:33:53 -0000 1.10 +++ sysdeps/mach/bits/libc-lock.h 18 Dec 2006 14:12:19 -0000 @@ -105,8 +105,7 @@ struct __libc_once #define __libc_once_define(CLASS,NAME) \ CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 } - -/* Call handler iff the first call. */ +/* Call INIT_FUNCTION iff the first call. */ #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \ do { \ __libc_lock_lock (ONCE_CONTROL.lock); \ @@ -116,6 +115,16 @@ struct __libc_once __libc_lock_unlock (ONCE_CONTROL.lock); \ } while (0) +/* Call INIT_FUNCTION iff the first call. Otherwise call ELSE_FUNCTION. */ +#define __libc_once_else(ONCE_CONTROL, INIT_FUNCTION, ELSE_FUNCTION) \ + do { \ + if (ONCE_CONTROL.done == 1) \ + (ELSE_FUNCTION) (); \ + else \ + __libc_once (ONCE_CONTROL, INIT_FUNCTION); \ + } while (0) + + #ifdef _LIBC /* We need portable names for some functions. E.g., when they are used as argument to __libc_cleanup_region_start. */ Index: sysdeps/mach/hurd/bits/libc-lock.h =================================================================== RCS file: /cvs/glibc/libc/sysdeps/mach/hurd/bits/libc-lock.h,v retrieving revision 1.4 diff -u -p -r1.4 libc-lock.h --- sysdeps/mach/hurd/bits/libc-lock.h 29 Sep 2003 21:55:41 -0000 1.4 +++ sysdeps/mach/hurd/bits/libc-lock.h 18 Dec 2006 14:12:19 -0000 @@ -175,7 +175,7 @@ struct __libc_once #define __libc_once_define(CLASS,NAME) \ CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 } -/* Call handler iff the first call. */ +/* Call INIT_FUNCTION iff the first call. */ #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \ do { \ __libc_lock_lock (ONCE_CONTROL.lock); \ @@ -185,6 +185,16 @@ struct __libc_once __libc_lock_unlock (ONCE_CONTROL.lock); \ } while (0) +/* Call INIT_FUNCTION iff the first call. Otherwise call ELSE_FUNCTION. */ +#define __libc_once_else(ONCE_CONTROL, INIT_FUNCTION, ELSE_FUNCTION) \ + do { \ + if (ONCE_CONTROL.done == 1) \ + ELSE_FUNCTION (); \ + else \ + __libc_once (ONCE_CONTROL, INIT_FUNCTION); \ + } while (0) + + #ifdef _LIBC /* We need portable names for some functions. E.g., when they are used as argument to __libc_cleanup_region_start. */ Index: nptl/sysdeps/pthread/bits/libc-lock.h =================================================================== RCS file: /cvs/glibc/libc/nptl/sysdeps/pthread/bits/libc-lock.h,v retrieving revision 1.19 diff -u -p -r1.19 libc-lock.h --- nptl/sysdeps/pthread/bits/libc-lock.h 5 Apr 2005 21:33:41 -0000 1.19 +++ nptl/sysdeps/pthread/bits/libc-lock.h 18 Dec 2006 14:12:19 -0000 @@ -350,7 +350,7 @@ typedef pthread_key_t __libc_key_t; CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT #endif -/* Call handler iff the first call. */ +/* Call INIT_FUNCTION iff the first call. */ #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \ do { \ if (PTF(__pthread_once) != NULL) \ @@ -361,6 +361,15 @@ typedef pthread_key_t __libc_key_t; } \ } while (0) +/* Call INIT_FUNCTION iff the first call. Otherwise call ELSE_FUNCTION. */ +#define __libc_once_else(ONCE_CONTROL, INIT_FUNCTION, ELSE_FUNCTION) \ + do { \ + if ((ONCE_CONTROL) != PTHREAD_ONCE_INIT) \ + (ELSE_FUNCTION) (); \ + else \ + __libc_once (ONCE_CONTROL, INIT_FUNCTION); \ + } while (0) + /* Note that for I/O cleanup handling we are using the old-style cancel handling. It does not have to be integrated with C++ snce Regards, Thomas
signature.asc
Description: Digital signature