Merge branch '1444-deprecate-isc_thread_key-API' into 'master'

Use native compiler Thread Local Storage instead of isc_thread_key API

Closes #1444

See merge request isc-projects/bind9!2680
This commit is contained in:
Ondřej Surý 2019-12-04 22:07:54 +00:00
commit da94ed13b8
41 changed files with 162 additions and 609 deletions

View file

@ -1,3 +1,7 @@
5331. [func] Use compiler-provided mechanisms for thread local
storage, and make the requirement for such mechanisms
explicit in configure. [GL #1444]
5330. [bug] 'configure --without-python' was ineffective if
PYTHON was set in the environment. [GL #1434]

View file

@ -5,16 +5,28 @@ Supported platforms
In general, this version of BIND will build and run on any POSIX-compliant
system with a C11-compliant C compiler, BSD-style sockets with
RFC-compliant IPv6 support, POSIX-compliant threads, the libuv
asynchronous I/O library, and the OpenSSL cryptography library. Atomic
operations support from the compiler is needed, either in the form of
builtin operations, C11 atomics, or the Interlocked family of functions on
Windows.
asynchronous I/O library, and the OpenSSL cryptography library.
BIND 9.15 requires fairly recent version of libuv library to run (>= 1.x).
For some of the older systems listed below, you will have to install
updated libuv package from sources such as EPEL, PPA and other native
sources for updated packages. The other option is to install libuv from
sources.
The following C11 features are used in BIND 9:
* Atomic operations support from the compiler is needed, either in the
form of builtin operations, C11 atomics, or the Interlocked family of
functions on Windows.
* Thread Local Storage support from the compiler is needed, either in
the form of C11 _Thread_local/thread_local, the __thread GCC
extension, or the __declspec(thread) MSVC extension on Windows.
BIND 9.15 requires a fairly recent version of libuv (at least 1.x). For
some of the older systems listed below, you will have to install an
updated libuv package from sources such as EPEL, PPA, or other native
sources for updated packages. The other option is to build and install
libuv from source.
Certain optional BIND features have additional library dependencies. These
include libxml2 and libjson-c for statistics, libmaxminddb for
geolocation, libfstrm and libprotobuf-c for DNSTAP, and libidn2 for
internationalized domain name conversion.
ISC regularly tests BIND on many operating systems and architectures, but
lacks the resources to test all of them. Consequently, ISC is only able to
@ -58,10 +70,10 @@ Server 2012 R2, none of these are tested regularly by ISC.
Community maintained
These systems may not all have easily available the required dependencies
for building BIND although it will be possible in many cases to compile
These systems may not all have the required dependencies for building BIND
easily available, although it will be possible in many cases to compile
those directly from source. The community and interested parties may wish
to help with maintenance and we welcome patch contributions, although we
to help with maintenance, and we welcome patch contributions, although we
cannot guarantee that we will accept them. All contributions will be
assessed against the risk of adverse effect on officially supported
platforms.
@ -84,6 +96,4 @@ These are platforms on which BIND 9.15 is known not to build or run:
* Platforms that don't support atomic operations (via compiler or
library)
* Linux without NPTL (Native POSIX Thread Library)
* Platforms where libuv cannot be compiled
Platform quirks
* Platforms on which libuv cannot be compiled

View file

@ -13,9 +13,17 @@
In general, this version of BIND will build and run on any POSIX-compliant
system with a C11-compliant C compiler, BSD-style sockets with RFC-compliant
IPv6 support, POSIX-compliant threads, the `libuv` asynchronous I/O library,
and the OpenSSL cryptography library. Atomic operations support from the
compiler is needed, either in the form of builtin operations, C11 atomics,
or the `Interlocked` family of functions on Windows.
and the OpenSSL cryptography library.
The following C11 features are used in BIND 9:
* Atomic operations support from the compiler is needed, either in the form of
builtin operations, C11 atomics, or the `Interlocked` family of functions on
Windows.
* Thread Local Storage support from the compiler is needed, either in the form
of C11 `_Thread_local`/`thread_local`, the `__thread` GCC extension, or
the `__declspec(thread)` MSVC extension on Windows.
BIND 9.15 requires a fairly recent version of `libuv` (at least 1.x). For
some of the older systems listed below, you will have to install an updated

View file

@ -709,8 +709,6 @@ main(int argc, char **argv) {
cfg_parser_destroy(&parser);
dns_name_destroy();
isc_log_destroy(&logc);
isc_mem_destroy(&mctx);

View file

@ -85,9 +85,9 @@ usage(void) {
static void
destroy(void) {
if (zone != NULL)
if (zone != NULL) {
dns_zone_detach(&zone);
dns_name_destroy();
}
}
/*% main processing routine */

View file

@ -4252,7 +4252,6 @@ destroy_libs(void) {
result = dns_name_settotextfilter(NULL);
check_result(result, "dns_name_settotextfilter");
#endif /* HAVE_LIBIDN2 */
dns_name_destroy();
if (commctx != NULL) {
debug("freeing commctx");

View file

@ -517,7 +517,6 @@ main(int argc, char **argv) {
}
cleanup_logging(&log);
dst_lib_destroy();
dns_name_destroy();
if (verbose > 10) {
isc_mem_stats(mctx, stdout);
}

View file

@ -439,7 +439,6 @@ main(int argc, char **argv) {
dns_rdataset_disassociate(&rdataset);
cleanup_logging(&log);
dst_lib_destroy();
dns_name_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
isc_mem_destroy(&mctx);

View file

@ -694,7 +694,6 @@ main(int argc, char **argv) {
cleanup_logging(&log);
dst_lib_destroy();
dns_name_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
isc_mem_free(mctx, label);

View file

@ -1222,7 +1222,6 @@ main(int argc, char **argv) {
cleanup_logging(&log);
dst_lib_destroy();
dns_name_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
isc_mem_destroy(&mctx);

View file

@ -3922,7 +3922,6 @@ main(int argc, char *argv[]) {
cleanup_logging(&log);
dst_lib_destroy();
dns_name_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
isc_mem_destroy(&mctx);

View file

@ -335,7 +335,6 @@ main(int argc, char *argv[]) {
cleanup_logging(&log);
dst_lib_destroy();
dns_name_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
isc_mem_destroy(&mctx);

View file

@ -113,8 +113,7 @@ named_geoip_load(char *dir) {
#endif
}
void
named_geoip_shutdown(void) {
void named_geoip_unload(void) {
#ifdef HAVE_GEOIP2
if (named_g_geoip->country != NULL) {
MMDB_close(named_g_geoip->country);
@ -136,5 +135,12 @@ named_geoip_shutdown(void) {
MMDB_close(named_g_geoip->domain);
named_g_geoip->domain = NULL;
}
#endif
}
void
named_geoip_shutdown(void) {
#ifdef HAVE_GEOIP2
named_geoip_unload();
#endif /* HAVE_GEOIP2 */
}

View file

@ -19,5 +19,8 @@ named_geoip_init(void);
void
named_geoip_load(char *dir);
void
named_geoip_unload(void);
void
named_geoip_shutdown(void);

View file

@ -1329,8 +1329,6 @@ cleanup(void) {
dlz_dlopen_clear();
#endif
dns_name_destroy();
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_MAIN,
ISC_LOG_NOTICE, "exiting");

View file

@ -8342,7 +8342,8 @@ load_configuration(const char *filename, named_server_t *server,
/*
* Release any previously opened GeoIP2 databases.
*/
named_geoip_shutdown();
named_geoip_unload();
/*
* Initialize GeoIP databases from the configured location.
* This should happen before configuring any ACLs, so that we
@ -9742,12 +9743,8 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_tsigkey_detach(&named_g_sessionkey);
dns_name_free(&named_g_sessionkeyname, server->mctx);
}
#ifdef HAVE_DNSTAP
dns_dt_shutdown();
#endif
#if defined(HAVE_GEOIP2)
named_geoip_shutdown();
dns_geoip_shutdown();
#endif /* HAVE_GEOIP2 */
dns_db_detach(&server->in_roothints);
@ -9869,7 +9866,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
/*
* GeoIP must be initialized before the interface
* manager (which includes the ACL environment)
* is created
* is created.
*/
named_geoip_init();
#endif /* HAVE_GEOIP2 */

View file

@ -3210,9 +3210,6 @@ cleanup(void) {
ddebug("Shutting down timer manager");
isc_timermgr_destroy(&timermgr);
ddebug("Destroying name state");
dns_name_destroy();
ddebug("Removing log context");
isc_log_destroy(&glctx);

View file

@ -1022,8 +1022,6 @@ main(int argc, char **argv) {
isc_mem_put(rndc_mctx, args, argslen);
isccc_ccmsg_invalidate(&ccmsg);
dns_name_destroy();
isc_buffer_free(&databuf);
if (show_final_mem)

View file

@ -145,7 +145,6 @@ main(int argc, char **argv) {
isc_log_setcontext(NULL);
dns_log_setcontext(NULL);
dst_lib_destroy();
dns_name_destroy();
isc_mem_destroy(&mctx);
return (0);
#else /* !USE_PKCS11 */

6
configure vendored
View file

@ -13616,8 +13616,7 @@ $as_echo "#define HAVE_TLS 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
as_fn_error $? "Thread Local Storage support required, update your toolchain to build BIND 9" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
@ -13655,8 +13654,7 @@ $as_echo "#define HAVE_TLS 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
as_fn_error $? "Thread Local Storage support required, update your toolchain to build BIND 9" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

View file

@ -389,7 +389,7 @@ AC_CHECK_HEADERS([threads.h],
AC_DEFINE([HAVE_THREAD_LOCAL],[1],[Define if thread_local keyword is available])
AC_DEFINE([HAVE_TLS],[1],[Define if Thread-Local Storage is available])
],[
AC_MSG_RESULT([no])
AC_MSG_ERROR([Thread Local Storage support required, update your toolchain to build BIND 9])
])
],[
AC_MSG_CHECKING([for Thread-Local Storage using __thread])
@ -405,7 +405,7 @@ AC_CHECK_HEADERS([threads.h],
AC_DEFINE([HAVE___THREAD],[1],[Define if __thread keyword is available])
AC_DEFINE([HAVE_TLS],[1],[Define if Thread-Local Storage is available])
],[
AC_MSG_RESULT([no])
AC_MSG_ERROR([Thread Local Storage support required, update your toolchain to build BIND 9])
])
])

View file

@ -127,59 +127,16 @@ struct dns_dtenv {
goto cleanup; \
} while (0)
static isc_mutex_t dt_mutex;
static bool dt_initialized = false;
static isc_thread_key_t dt_key;
static isc_once_t mutex_once = ISC_ONCE_INIT;
static isc_mem_t *dt_mctx = NULL;
/*
* Change under task exclusive.
*/
static unsigned int generation;
typedef struct ioq {
unsigned int generation;
struct fstrm_iothr_queue *ioq;
} dt__ioq_t;
static void
mutex_init(void) {
isc_mutex_init(&dt_mutex);
}
static void
dtfree(void *arg) {
free(arg);
isc_thread_key_setspecific(dt_key, NULL);
}
ISC_THREAD_LOCAL dt__ioq_t dt_ioq = { 0 };
static isc_result_t
dt_init(void) {
isc_result_t result;
result = isc_once_do(&mutex_once, mutex_init);
if (result != ISC_R_SUCCESS)
return (result);
if (dt_initialized)
return (ISC_R_SUCCESS);
LOCK(&dt_mutex);
if (!dt_initialized) {
int ret;
if (dt_mctx == NULL) {
isc_mem_create(&dt_mctx);
}
isc_mem_setname(dt_mctx, "dt", NULL);
isc_mem_setdestroycheck(dt_mctx, false);
ret = isc_thread_key_create(&dt_key, dtfree);
if (ret == 0)
dt_initialized = true;
else
result = ISC_R_FAILURE;
}
UNLOCK(&dt_mutex);
return (result);
}
static atomic_uint_fast32_t global_generation;
isc_result_t
dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
@ -202,7 +159,7 @@ dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
DNS_LOGMODULE_DNSTAP, ISC_LOG_INFO,
"opening dnstap destination '%s'", path);
generation++;
atomic_fetch_add_release(&global_generation, 1);
env = isc_mem_get(mctx, sizeof(dns_dtenv_t));
@ -380,7 +337,7 @@ dns_dt_reopen(dns_dtenv_t *env, int roll) {
(roll < 0) ? "reopening" : "rolling",
env->path);
generation++;
atomic_fetch_add_release(&global_generation, 1);
if (env->iothr != NULL) {
fstrm_iothr_destroy(&env->iothr);
@ -474,49 +431,33 @@ dns_dt_setversion(dns_dtenv_t *env, const char *version) {
return (toregion(env, &env->version, version));
}
static void
set_dt_ioq(unsigned int generation, struct fstrm_iothr_queue *ioq) {
dt_ioq.generation = generation;
dt_ioq.ioq = ioq;
}
static struct fstrm_iothr_queue *
dt_queue(dns_dtenv_t *env) {
isc_result_t result;
struct ioq {
unsigned int generation;
struct fstrm_iothr_queue *ioq;
} *ioq;
REQUIRE(VALID_DTENV(env));
if (env->iothr == NULL)
return (NULL);
unsigned int generation;
result = dt_init();
if (result != ISC_R_SUCCESS)
if (env->iothr == NULL) {
return (NULL);
ioq = (struct ioq *)isc_thread_key_getspecific(dt_key);
if (ioq != NULL && ioq->generation != generation) {
result = isc_thread_key_setspecific(dt_key, NULL);
if (result != ISC_R_SUCCESS)
return (NULL);
free(ioq);
ioq = NULL;
}
if (ioq == NULL) {
ioq = malloc(sizeof(*ioq));
if (ioq == NULL)
return (NULL);
ioq->generation = generation;
ioq->ioq = fstrm_iothr_get_input_queue(env->iothr);
if (ioq->ioq == NULL) {
free(ioq);
return (NULL);
}
result = isc_thread_key_setspecific(dt_key, ioq);
if (result != ISC_R_SUCCESS) {
free(ioq);
return (NULL);
}
}
return (ioq->ioq);
generation = atomic_load_acquire(&global_generation);
if (dt_ioq.ioq != NULL && dt_ioq.generation != generation) {
set_dt_ioq(0, NULL);
}
if (dt_ioq.ioq == NULL) {
struct fstrm_iothr_queue *ioq =
fstrm_iothr_get_input_queue(env->iothr);
set_dt_ioq(generation, ioq);
}
return (dt_ioq.ioq);
}
void
@ -547,7 +488,7 @@ destroy(dns_dtenv_t *env) {
"closing dnstap");
env->magic = 0;
generation++;
atomic_fetch_add(&global_generation, 1);
if (env->iothr != NULL)
fstrm_iothr_destroy(&env->iothr);
@ -927,12 +868,6 @@ dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype,
send_dt(view->dtenv, dm.buf, dm.len);
}
void
dns_dt_shutdown() {
if (dt_mctx != NULL)
isc_mem_detach(&dt_mctx);
}
static isc_result_t
putstr(isc_buffer_t **b, const char *str) {
isc_result_t result;

View file

@ -64,7 +64,6 @@
*/
typedef struct geoip_state {
isc_mem_t *mctx;
uint16_t subtype;
const MMDB_s *db;
isc_netaddr_t addr;
@ -72,117 +71,28 @@ typedef struct geoip_state {
MMDB_entry_s entry;
} geoip_state_t;
static isc_mutex_t key_mutex;
static bool state_key_initialized = false;
static isc_thread_key_t state_key;
static isc_once_t mutex_once = ISC_ONCE_INIT;
static isc_mem_t *state_mctx = NULL;
ISC_THREAD_LOCAL geoip_state_t geoip_state = { 0 };
static void
key_mutex_init(void) {
isc_mutex_init(&key_mutex);
}
static void
free_state(void *arg) {
geoip_state_t *state = arg;
if (state != NULL) {
isc_mem_putanddetach(&state->mctx,
state, sizeof(geoip_state_t));
}
isc_thread_key_setspecific(state_key, NULL);
}
static isc_result_t
state_key_init(void) {
isc_result_t result;
result = isc_once_do(&mutex_once, key_mutex_init);
if (result != ISC_R_SUCCESS) {
return (result);
}
if (!state_key_initialized) {
LOCK(&key_mutex);
if (!state_key_initialized) {
int ret;
if (state_mctx == NULL) {
isc_mem_create(&state_mctx);
}
isc_mem_setname(state_mctx, "geoip_state", NULL);
isc_mem_setdestroycheck(state_mctx, false);
ret = isc_thread_key_create(&state_key, free_state);
if (ret == 0) {
state_key_initialized = true;
} else {
result = ISC_R_FAILURE;
}
}
UNLOCK(&key_mutex);
}
return (result);
}
static isc_result_t
set_state(const MMDB_s *db, const isc_netaddr_t *addr,
MMDB_lookup_result_s mmresult, MMDB_entry_s entry,
geoip_state_t **statep)
MMDB_lookup_result_s mmresult, MMDB_entry_s entry)
{
geoip_state_t *state = NULL;
isc_result_t result;
result = state_key_init();
if (result != ISC_R_SUCCESS) {
return (result);
}
state = (geoip_state_t *) isc_thread_key_getspecific(state_key);
if (state == NULL) {
state = isc_mem_get(state_mctx, sizeof(geoip_state_t));
memset(state, 0, sizeof(*state));
result = isc_thread_key_setspecific(state_key, state);
if (result != ISC_R_SUCCESS) {
isc_mem_put(state_mctx, state, sizeof(geoip_state_t));
return (result);
}
isc_mem_attach(state_mctx, &state->mctx);
}
state->db = db;
state->addr = *addr;
state->mmresult = mmresult;
state->entry = entry;
if (statep != NULL) {
*statep = state;
}
return (ISC_R_SUCCESS);
geoip_state.db = db;
geoip_state.addr = *addr;
geoip_state.mmresult = mmresult;
geoip_state.entry = entry;
}
static geoip_state_t *
get_entry_for(MMDB_s * const db, const isc_netaddr_t *addr) {
isc_result_t result;
isc_sockaddr_t sa;
geoip_state_t *state;
MMDB_lookup_result_s match;
int err;
result = state_key_init();
if (result != ISC_R_SUCCESS) {
return (NULL);
}
state = (geoip_state_t *) isc_thread_key_getspecific(state_key);
if (state != NULL) {
if (db == state->db && isc_netaddr_equal(addr, &state->addr)) {
return (state);
}
if (db == geoip_state.db &&
isc_netaddr_equal(addr, &geoip_state.addr))
{
return (&geoip_state);
}
isc_sockaddr_fromnetaddr(&sa, addr, 0);
@ -191,12 +101,9 @@ get_entry_for(MMDB_s * const db, const isc_netaddr_t *addr) {
return (NULL);
}
result = set_state(db, addr, match, match.entry, &state);
if (result != ISC_R_SUCCESS) {
return (NULL);
}
set_state(db, addr, match, match.entry);
return (state);
return (&geoip_state);
}
static dns_geoip_subtype_t
@ -482,10 +389,3 @@ dns_geoip_match(const isc_netaddr_t *reqaddr,
*/
return (false);
}
void
dns_geoip_shutdown(void) {
if (state_mctx != NULL) {
isc_mem_detach(&state_mctx);
}
}

View file

@ -267,13 +267,6 @@ dns_dt_getstats(dns_dtenv_t *env, isc_stats_t **statsp);
*\li ISC_R_NOTFOUND
*/
void
dns_dt_shutdown(void);
/*%<
* Shuts down dnstap and frees global resources. This function must only
* be called immediately before server shutdown.
*/
void
dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype,
isc_sockaddr_t *qaddr, isc_sockaddr_t *dstaddr,

View file

@ -105,9 +105,6 @@ dns_geoip_match(const isc_netaddr_t *reqaddr,
const dns_geoip_databases_t *geoip,
const dns_geoip_elem_t *elt);
void
dns_geoip_shutdown(void);
ISC_LANG_ENDDECLS
#endif /* HAVE_GEOIP2 */

View file

@ -197,8 +197,8 @@ LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_wildcardname;
* 'target' is the buffer to be converted. The region to be converted
* is from 'buffer'->base + 'used_org' to the end of the used region.
*/
typedef isc_result_t (*dns_name_totextfilter_t)(isc_buffer_t *target,
unsigned int used_org);
typedef isc_result_t (dns_name_totextfilter_t)(isc_buffer_t *target,
unsigned int used_org);
/***
*** Initialization
@ -1217,7 +1217,7 @@ dns_name_fromstring2(dns_name_t *target, const char *src,
*/
isc_result_t
dns_name_settotextfilter(dns_name_totextfilter_t proc);
dns_name_settotextfilter(dns_name_totextfilter_t *proc);
/*%<
* Set / clear a thread specific function 'proc' to be called at the
* end of dns_name_totext().
@ -1296,18 +1296,6 @@ dns_name_internalwildcard(const dns_name_t *name);
* \li 'name' to be valid.
*/
void
dns_name_destroy(void);
/*%<
* Cleanup dns_name_settotextfilter() / dns_name_totext() state.
*
* This should be called as part of the final cleanup process.
*
* Note: dns_name_settotextfilter(NULL); should be called for all
* threads which have called dns_name_settotextfilter() with a
* non-NULL argument prior to calling dns_name_destroy();
*/
bool
dns_name_isdnssd(const dns_name_t *owner);
/*%<

View file

@ -163,11 +163,7 @@ LIBDNS_EXTERNAL_DATA const dns_name_t *dns_wildcardname = &wild;
/*
* dns_name_t to text post-conversion procedure.
*/
static int thread_key_initialized = 0;
static isc_mutex_t thread_key_mutex;
static isc_mem_t *thread_key_mctx = NULL;
static isc_thread_key_t totext_filter_proc_key;
static isc_once_t once = ISC_ONCE_INIT;
ISC_THREAD_LOCAL dns_name_totextfilter_t *totext_filter_proc = NULL;
static void
set_offsets(const dns_name_t *name, unsigned char *offsets,
@ -1272,52 +1268,6 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
return (ISC_R_SUCCESS);
}
static void
free_specific(void *arg) {
dns_name_totextfilter_t *mem = arg;
isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
/* Stop use being called again. */
(void)isc_thread_key_setspecific(totext_filter_proc_key, NULL);
}
static void
thread_key_mutex_init(void) {
isc_mutex_init(&thread_key_mutex);
}
static isc_result_t
totext_filter_proc_key_init(void) {
isc_result_t result;
/*
* We need the call to isc_once_do() to support profiled mutex
* otherwise thread_key_mutex could be initialized at compile time.
*/
result = isc_once_do(&once, thread_key_mutex_init);
if (result != ISC_R_SUCCESS)
return (result);
if (!thread_key_initialized) {
LOCK(&thread_key_mutex);
if (thread_key_mctx == NULL) {
isc_mem_create(&thread_key_mctx);
}
isc_mem_setname(thread_key_mctx, "threadkey", NULL);
isc_mem_setdestroycheck(thread_key_mctx, false);
if (!thread_key_initialized &&
isc_thread_key_create(&totext_filter_proc_key,
free_specific) != 0) {
result = ISC_R_FAILURE;
isc_mem_detach(&thread_key_mctx);
} else {
thread_key_initialized = 1;
}
UNLOCK(&thread_key_mutex);
}
return (result);
}
isc_result_t
dns_name_totext(const dns_name_t *name, bool omit_final_dot,
isc_buffer_t *target)
@ -1346,9 +1296,6 @@ dns_name_totext2(const dns_name_t *name, unsigned int options,
unsigned int labels;
bool saw_root = false;
unsigned int oused;
dns_name_totextfilter_t *mem;
dns_name_totextfilter_t totext_filter_proc = NULL;
isc_result_t result;
bool omit_final_dot = ((options & DNS_NAME_OMITFINALDOT) != 0);
/*
@ -1360,9 +1307,6 @@ dns_name_totext2(const dns_name_t *name, unsigned int options,
oused = target->used;
result = totext_filter_proc_key_init();
if (result != ISC_R_SUCCESS)
return (result);
ndata = name->ndata;
nlen = name->length;
labels = name->labels;
@ -1502,11 +1446,9 @@ dns_name_totext2(const dns_name_t *name, unsigned int options,
}
isc_buffer_add(target, tlen - trem);
mem = isc_thread_key_getspecific(totext_filter_proc_key);
if (mem != NULL)
totext_filter_proc = *mem;
if (totext_filter_proc != NULL)
return ((*totext_filter_proc)(target, oused));
if (totext_filter_proc != NULL) {
return ((totext_filter_proc)(target, oused));
}
return (ISC_R_SUCCESS);
}
@ -2320,40 +2262,23 @@ dns_name_print(const dns_name_t *name, FILE *stream) {
}
isc_result_t
dns_name_settotextfilter(dns_name_totextfilter_t proc) {
isc_result_t result;
dns_name_totextfilter_t *mem;
int res;
result = totext_filter_proc_key_init();
if (result != ISC_R_SUCCESS)
return (result);
dns_name_settotextfilter(dns_name_totextfilter_t *proc) {
/*
* If we already have been here set / clear as appropriate.
* Otherwise allocate memory.
*/
mem = isc_thread_key_getspecific(totext_filter_proc_key);
if (mem != NULL && proc != NULL) {
*mem = proc;
if (totext_filter_proc != NULL && proc != NULL) {
if (totext_filter_proc == proc) {
return (ISC_R_SUCCESS);
}
}
if (proc == NULL && totext_filter_proc != NULL) {
totext_filter_proc = NULL;
return (ISC_R_SUCCESS);
}
if (proc == NULL) {
if (mem != NULL)
isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
res = isc_thread_key_setspecific(totext_filter_proc_key, NULL);
if (res != 0)
result = ISC_R_UNEXPECTED;
return (result);
}
mem = isc_mem_get(thread_key_mctx, sizeof(*mem));
*mem = proc;
if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) {
isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
result = ISC_R_UNEXPECTED;
}
return (result);
totext_filter_proc = proc;
return (ISC_R_SUCCESS);
}
void
@ -2511,21 +2436,6 @@ dns_name_copynf(const dns_name_t *source, dns_name_t *dest)
RUNTIME_CHECK(name_copy(source, dest, dest->buffer) == ISC_R_SUCCESS);
}
void
dns_name_destroy(void) {
RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init)
== ISC_R_SUCCESS);
LOCK(&thread_key_mutex);
if (thread_key_initialized) {
isc_mem_detach(&thread_key_mctx);
isc_thread_key_delete(totext_filter_proc_key);
thread_key_initialized = 0;
}
UNLOCK(&thread_key_mutex);
}
/*
* Service Discovery Prefixes RFC 6763.
*/

View file

@ -132,8 +132,6 @@ create_test(void **state) {
}
cleanup();
dns_dt_shutdown();
}
/* send dnstap messages */
@ -263,7 +261,6 @@ send_test(void **state) {
dns_dt_detach(&view->dtenv);
dns_dt_detach(&dtenv);
dns_dt_shutdown();
dns_view_detach(&view);
result = dns_dt_open(TAPFILE, dns_dtmode_file, dt_mctx, &handle);

View file

@ -334,17 +334,17 @@ int
main(void) {
#if defined(HAVE_GEOIP2)
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(country, _setup, _teardown),
cmocka_unit_test_setup_teardown(country_v6, _setup, _teardown),
cmocka_unit_test_setup_teardown(city, _setup, _teardown),
cmocka_unit_test_setup_teardown(city_v6, _setup, _teardown),
cmocka_unit_test_setup_teardown(asnum, _setup, _teardown),
cmocka_unit_test_setup_teardown(isp, _setup, _teardown),
cmocka_unit_test_setup_teardown(org, _setup, _teardown),
cmocka_unit_test_setup_teardown(domain, _setup, _teardown),
cmocka_unit_test(country),
cmocka_unit_test(country_v6),
cmocka_unit_test(city),
cmocka_unit_test(city_v6),
cmocka_unit_test(asnum),
cmocka_unit_test(isp),
cmocka_unit_test(org),
cmocka_unit_test(domain),
};
return (cmocka_run_group_tests(tests, NULL, NULL));
return (cmocka_run_group_tests(tests, _setup, _teardown));
#else
print_message("1..0 # Skip GeoIP not enabled\n");
#endif

View file

@ -354,7 +354,6 @@ dns_dt_send
dns_dt_setidentity
dns_dt_setupfile
dns_dt_setversion
dns_dt_shutdown
dns_dtdata_free
@END NOTYET
dns_dumpctx_attach
@ -385,7 +384,6 @@ dns_generalstats_dump
dns_generalstats_increment
@IF GEOIP
dns_geoip_match
dns_geoip_shutdown
@END GEOIP
dns_hashalg_fromtext
dns_ipkeylist_clear
@ -584,7 +582,6 @@ dns_name_concatenate
dns_name_copy
dns_name_copynf
dns_name_countlabels
dns_name_destroy
dns_name_digest
dns_name_downcase
dns_name_dup

View file

@ -42,11 +42,7 @@
#define DNS_CONF "/etc/dns.conf"
#endif
static bool thread_key_initialized = false;
static isc_mutex_t thread_key_mutex;
static isc_thread_key_t irs_context_key;
static isc_once_t once = ISC_ONCE_INIT;
ISC_THREAD_LOCAL irs_context_t *irs_context = NULL;
struct irs_context {
/*
@ -119,68 +115,20 @@ ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp,
return (result);
}
static void
free_specific_context(void *arg) {
irs_context_t *context = arg;
irs_context_destroy(&context);
isc_thread_key_setspecific(irs_context_key, NULL);
}
static void
thread_key_mutex_init(void) {
isc_mutex_init(&thread_key_mutex);
}
static isc_result_t
thread_key_init(void) {
isc_result_t result;
result = isc_once_do(&once, thread_key_mutex_init);
if (result != ISC_R_SUCCESS)
return (result);
if (!thread_key_initialized) {
LOCK(&thread_key_mutex);
if (!thread_key_initialized &&
isc_thread_key_create(&irs_context_key,
free_specific_context) != 0) {
result = ISC_R_FAILURE;
} else
thread_key_initialized = true;
UNLOCK(&thread_key_mutex);
}
return (result);
}
isc_result_t
irs_context_get(irs_context_t **contextp) {
irs_context_t *context;
isc_result_t result;
REQUIRE(contextp != NULL && *contextp == NULL);
result = thread_key_init();
if (result != ISC_R_SUCCESS)
return (result);
context = isc_thread_key_getspecific(irs_context_key);
if (context == NULL) {
result = irs_context_create(&context);
if (result != ISC_R_SUCCESS)
return (result);
result = isc_thread_key_setspecific(irs_context_key, context);
if (irs_context == NULL) {
result = irs_context_create(&irs_context);
if (result != ISC_R_SUCCESS) {
irs_context_destroy(&context);
return (result);
}
}
*contextp = context;
*contextp = irs_context;
return (ISC_R_SUCCESS);
}
@ -289,6 +237,7 @@ irs_context_destroy(irs_context_t **contextp) {
REQUIRE(contextp != NULL);
context = *contextp;
REQUIRE(IRS_CONTEXT_VALID(context));
*contextp = irs_context = NULL;
isc_task_detach(&context->task);
irs_dnsconf_destroy(&context->dnsconf);
@ -302,9 +251,6 @@ irs_context_destroy(irs_context_t **contextp) {
isc_mem_putanddetach(&context->mctx, context, sizeof(*context));
*contextp = NULL;
(void)isc_thread_key_setspecific(irs_context_key, NULL);
}
isc_mem_t *

View file

@ -51,6 +51,7 @@
#include <isc/string.h>
#include <isc/mem.h>
#include <isc/util.h>
#include <isc/thread.h>
#define HP_MAX_THREADS 128
#define HP_MAX_HPS 4 /* This is named 'K' in the HP paper */
@ -64,20 +65,7 @@
static atomic_int_fast32_t tid_v_base = ATOMIC_VAR_INIT(0);
#if defined(HAVE_TLS)
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
static thread_local int tid_v = TID_UNKNOWN;
#elif defined(HAVE___THREAD)
static __thread int tid_v = TID_UNKNOWN;
#elif defined(HAVE___DECLSPEC_THREAD)
static __declspec( thread ) int tid_v = TID_UNKNOWN;
#else /* if defined(HAVE_THREAD_LOCAL) */
#error "Unknown method for defining a TLS variable!"
#endif /* if defined(HAVE_THREAD_LOCAL) */
#else /* if defined(HAVE_TLS) */
#error "Thread-local storage support is required!"
#endif /* if defined(HAVE_TLS) */
ISC_THREAD_LOCAL int tid_v = TID_UNKNOWN;
typedef struct retirelist {
int size;

View file

@ -18,14 +18,6 @@
***** Platform-dependent defines.
*****/
/***
*** Thread-Local Storage
***/
#ifdef HAVE___THREAD
#define thread_local __thread
#endif
/***
*** Default strerror_r buffer size
***/

View file

@ -31,7 +31,6 @@
#include <isc/util.h>
#define ISC_NETMGR_TID_UNKNOWN -1
#define ISC_NETMGR_TID_NOTLS -2
/*
* Single network event loop worker.

View file

@ -40,20 +40,7 @@
* request using async_cb.
*/
#if defined(HAVE_TLS)
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
static thread_local int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
#elif defined(HAVE___THREAD)
static __thread int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
#elif defined(HAVE___DECLSPEC_THREAD)
static __declspec( thread ) int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
#else /* if defined(HAVE_THREAD_LOCAL) */
#error "Unknown method for defining a TLS variable!"
#endif /* if defined(HAVE_THREAD_LOCAL) */
#else /* if defined(HAVE_TLS) */
static int isc__nm_tid_v = ISC_NETMGR_TID_NOTLS;
#endif /* if defined(HAVE_TLS) */
ISC_THREAD_LOCAL int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
static void
nmsocket_maybe_destroy(isc_nmsocket_t *sock);

View file

@ -30,7 +30,6 @@ typedef pthread_t isc_thread_t;
typedef void * isc_threadresult_t;
typedef void * isc_threadarg_t;
typedef isc_threadresult_t (*isc_threadfunc_t)(isc_threadarg_t);
typedef pthread_key_t isc_thread_key_t;
void
isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *);
@ -53,10 +52,22 @@ isc_thread_setaffinity(int cpu);
#define isc_thread_self \
(unsigned long)pthread_self
#define isc_thread_key_create pthread_key_create
#define isc_thread_key_getspecific pthread_getspecific
#define isc_thread_key_setspecific pthread_setspecific
#define isc_thread_key_delete pthread_key_delete
/***
*** Thread-Local Storage
***/
#if defined(HAVE_TLS)
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
#define ISC_THREAD_LOCAL static thread_local
#elif defined(HAVE___THREAD)
#define ISC_THREAD_LOCAL static __thread
#else /* if defined(HAVE_THREAD_LOCAL) */
#error "Unknown method for defining a TLS variable!"
#endif /* if defined(HAVE_THREAD_LOCAL) */
#else /* if defined(HAVE_TLS) */
#error "Thread-local storage support is required!"
#endif /* if defined(HAVE_TLS) */
ISC_LANG_ENDDECLS

View file

@ -36,6 +36,7 @@
#include <isc/platform.h>
#include <isc/random.h>
#include <isc/result.h>
#include <isc/thread.h>
#include <isc/types.h>
#include <isc/util.h>
@ -60,20 +61,7 @@
*/
#include "xoshiro128starstar.c"
#if defined(HAVE_TLS)
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
static thread_local isc_once_t isc_random_once = ISC_ONCE_INIT;
#elif defined(HAVE___THREAD)
static __thread isc_once_t isc_random_once = ISC_ONCE_INIT;
#elif defined(HAVE___DECLSPEC_THREAD)
static __declspec( thread ) isc_once_t isc_random_once = ISC_ONCE_INIT;
#else
#error "Unknown method for defining a TLS variable!"
#endif
#else
static isc_once_t isc_random_once = ISC_ONCE_INIT;
#endif
ISC_THREAD_LOCAL isc_once_t isc_random_once = ISC_ONCE_INIT;
static void
isc_random_initialize(void) {

View file

@ -61,7 +61,6 @@ typedef HANDLE isc_thread_t;
typedef DWORD isc_threadresult_t;
typedef void * isc_threadarg_t;
typedef isc_threadresult_t (WINAPI *isc_threadfunc_t)(isc_threadarg_t);
typedef DWORD isc_thread_key_t;
#define isc_thread_self (unsigned long)GetCurrentThreadId
@ -82,20 +81,14 @@ isc_thread_setname(isc_thread_t, const char *);
isc_result_t
isc_thread_setaffinity(int cpu);
int
isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *));
int
isc_thread_key_delete(isc_thread_key_t key);
void *
isc_thread_key_getspecific(isc_thread_key_t);
int
isc_thread_key_setspecific(isc_thread_key_t key, void *value);
#define isc_thread_yield() Sleep(0)
#if HAVE___DECLSPEC_THREAD
#define ISC_THREAD_LOCAL static __declspec( thread )
#else
#error "Thread-local storage support is required!"
#endif
ISC_LANG_ENDDECLS
#endif /* ISC_THREAD_H */

View file

@ -651,10 +651,6 @@ isc_taskpool_setprivilege
isc_taskpool_size
isc_thread_create
isc_thread_join
isc_thread_key_create
isc_thread_key_delete
isc_thread_key_getspecific
isc_thread_key_setspecific
isc_thread_setaffinity
isc_thread_setconcurrency
isc_thread_setname

View file

@ -73,25 +73,3 @@ isc_thread_setaffinity(int cpu) {
/* no-op on Windows for now */
return (ISC_R_SUCCESS);
}
void *
isc_thread_key_getspecific(isc_thread_key_t key) {
return(TlsGetValue(key));
}
int
isc_thread_key_setspecific(isc_thread_key_t key, void *value) {
return (TlsSetValue(key, value) ? 0 : GetLastError());
}
int
isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *)) {
*key = TlsAlloc();
return ((*key != -1) ? 0 : GetLastError());
}
int
isc_thread_key_delete(isc_thread_key_t key) {
return (TlsFree(key) ? 0 : GetLastError());
}

View file

@ -22,6 +22,8 @@
#include <inttypes.h>
#include <isc/thread.h>
/*
* This is xoshiro128** 1.0, our 32-bit all-purpose, rock-solid generator.
* It has excellent (sub-ns) speed, a state size (128 bits) that is large
@ -32,56 +34,7 @@
*
* The state must be seeded so that it is not everywhere zero.
*/
#if defined(HAVE_TLS)
#define _LOCK() {};
#define _UNLOCK() {};
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
static thread_local uint32_t seed[4];
#elif defined(HAVE___THREAD)
static __thread uint32_t seed[4];
#elif defined(HAVE___DECLSPEC_THREAD)
static __declspec( thread ) uint32_t seed[4];
#else
#error "Unknown method for defining a TLS variable!"
#endif
#else
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
static volatile void *_mutex = NULL;
/*
* Initialize the mutex on the first lock attempt. On collision, each thread
* will attempt to allocate a mutex and compare-and-swap it into place as the
* global mutex. On failure to swap in the global mutex, the mutex is closed.
*/
#define _LOCK() \
do { \
if (!_mutex) { \
void *p = CreateMutex(NULL, FALSE, NULL); \
if (InterlockedCompareExchangePointer \
((void **)&_mutex, (void *)p, NULL)) { \
CloseHandle(p); \
} \
} \
WaitForSingleObject(_mutex, INFINITE); \
} while (0)
#define _UNLOCK() ReleaseMutex(_mutex)
#else /* defined(_WIN32) || defined(_WIN64) */
#include <pthread.h>
static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
#define _LOCK() RUNTIME_CHECK(pthread_mutex_lock(&_mutex)==0)
#define _UNLOCK() RUNTIME_CHECK(pthread_mutex_unlock(&_mutex)==0)
#endif /* defined(_WIN32) || defined(_WIN64) */
static uint32_t seed[4];
#endif /* defined(HAVE_TLS) */
ISC_THREAD_LOCAL uint32_t seed[4] = { 0 };
static inline uint32_t rotl(const uint32_t x, int k) {
return (x << k) | (x >> (32 - k));
@ -91,8 +44,6 @@ static inline uint32_t
next(void) {
uint32_t result_starstar, t;
_LOCK();
result_starstar = rotl(seed[0] * 5, 7) * 9;
t = seed[1] << 9;
@ -105,7 +56,5 @@ next(void) {
seed[3] = rotl(seed[3], 11);
_UNLOCK();
return (result_starstar);
}