From aab4df0fb51660300559f5f29290709db2f7bfee Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Sat, 19 Sep 2009 10:09:39 -0700 Subject: resolv.c: add support for per thread res_state Signed-off-by: Austin Foxley --- libc/inet/Makefile.in | 4 ++-- libc/inet/_res_state.c | 8 ++++++++ libc/inet/resolv.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 libc/inet/_res_state.c (limited to 'libc') diff --git a/libc/inet/Makefile.in b/libc/inet/Makefile.in index cf689d806..23e8732b2 100644 --- a/libc/inet/Makefile.in +++ b/libc/inet/Makefile.in @@ -43,8 +43,8 @@ resolv_CSRC += \ getnameinfo.c \ gethostbyaddr_r.c gethostbyname_r.c gethostbyname2_r.c gethostent_r.c \ gethostbyaddr.c gethostbyname.c gethostbyname2.c gethostent.c \ - res_init.c res_query.c res_comp.c ns_name.c - + res_init.c res_query.c res_comp.c ns_name.c \ + _res_state.c ifneq ($(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6),) CSRC += $(resolv_CSRC) ## # unused ATM diff --git a/libc/inet/_res_state.c b/libc/inet/_res_state.c new file mode 100644 index 000000000..8ca4ac192 --- /dev/null +++ b/libc/inet/_res_state.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2006 Steven J. Hill + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_res_state +#include "resolv.c" diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 109ae020f..ca191ac4e 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -2843,9 +2843,6 @@ libc_hidden_def(ns_name_unpack) #ifdef L_res_init -/* Protected by __resolv_lock */ -struct __res_state _res; - /* Will be called under __resolv_lock. */ static void res_sync_func(void) { @@ -2988,8 +2985,60 @@ void res_close(void) __UCLIBC_MUTEX_UNLOCK(__resolv_lock); } #endif + +/* This needs to be after the use of _res in res_init, above. */ +#undef _res + +#ifndef __UCLIBC_HAS_THREADS__ +/* The resolver state for use by single-threaded programs. + This differs from plain `struct __res_state _res;' in that it doesn't + create a common definition, but a plain symbol that resides in .bss, + which can have an alias. */ +struct __res_state _res __attribute__((section (".bss"))); +struct __res_state *__resp = &_res; +#else //__UCLIBC_HAS_THREADS__ +struct __res_state _res __attribute__((section (".bss"))) attribute_hidden; + +# if defined __UCLIBC_HAS_TLS__ +# undef __resp +__thread struct __res_state *__resp = &_res; +/* + * FIXME: Add usage of hidden attribute for this when used in the shared + * library. It currently crashes the linker when doing section + * relocations. + */ +extern __thread struct __res_state *__libc_resp + __attribute__ ((alias ("__resp"))); +# else +# undef __resp +struct __res_state *__resp = &_res; +# endif +#endif + #endif /* L_res_init */ +#ifdef L_res_state +# if defined __UCLIBC_HAS_TLS__ +struct __res_state * +__res_state (void) +{ + return __resp; +} +# else +# undef _res +extern struct __res_state _res; + +/* When threaded, _res may be a per-thread variable. */ +struct __res_state * +weak_const_function +__res_state (void) +{ + return &_res; +} +# endif + +#endif + #ifdef L_res_query -- cgit v1.2.3