summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authoreric <eric@openbsd.org>2012-04-15 22:25:14 +0000
committereric <eric@openbsd.org>2012-04-15 22:25:14 +0000
commit12bff0977d2e1b1a9e9b71035844951c830b1a0f (patch)
treee245e60fd4cd60a0798193a64e5634e682c4db97 /lib/libc
parentcalling getnameinfo here is a bad idea. use inet_ntop. (diff)
downloadwireguard-openbsd-12bff0977d2e1b1a9e9b71035844951c830b1a0f.tar.xz
wireguard-openbsd-12bff0977d2e1b1a9e9b71035844951c830b1a0f.zip
Create a new resolver for each thread. It will be done differently
eventually, but it's enough for now to make the blocking API fully thread-safe without locking.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/asr/asr.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/lib/libc/asr/asr.c b/lib/libc/asr/asr.c
index bf0238c1e0d..48460d31ac0 100644
--- a/lib/libc/asr/asr.c
+++ b/lib/libc/asr/asr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr.c,v 1.2 2012/04/14 12:06:13 eric Exp $ */
+/* $OpenBSD: asr.c,v 1.3 2012/04/15 22:25:14 eric Exp $ */
/*
* Copyright (c) 2010-2012 Eric Faurot <eric@openbsd.org>
*
@@ -34,6 +34,7 @@
#include "asr.h"
#include "asr_private.h"
+#include "thread_private.h"
#define DEFAULT_CONFFILE "/etc/resolv.conf"
#define DEFAULT_HOSTFILE "/etc/hosts"
@@ -57,7 +58,8 @@ static int asr_ndots(const char *);
static void asr_ctx_envopts(struct asr_ctx *);
static int pass0(char **, int, struct asr_ctx *);
-static struct asr * _default_resolver = NULL;
+static void *__THREAD_NAME(_asr);
+static struct asr *_asr = NULL;
/* Allocate and configure an async "resolver". */
struct asr *
@@ -124,11 +126,14 @@ async_resolver(const char *conf)
void
async_resolver_done(struct asr *asr)
{
+ struct asr **priv;
+
if (asr == NULL) {
- if (_default_resolver == NULL)
+ priv = _THREAD_PRIVATE(_asr, asr, &_asr);
+ if (*priv == NULL)
return;
- asr = _default_resolver;
- _default_resolver = NULL;
+ asr = *priv;
+ *priv = NULL;
}
asr_ctx_unref(asr->a_ctx);
@@ -321,16 +326,21 @@ async_free(struct async *as)
struct asr_ctx *
asr_use_resolver(struct asr *asr)
{
- if (asr == NULL) {
- /* We want the use the global resolver. */
+ struct asr **priv;
- /* _THREAD_PRIVATE_MUTEX_LOCK(_asr_mutex); */
- if (_default_resolver != NULL)
- asr_check_reload(asr);
- else
- _default_resolver = async_resolver(NULL);
- asr = _default_resolver;
- /* _THREAD_PRIVATE_MUTEX_UNLOCK(_asr_mutex); */
+ if (asr == NULL) {
+ /* Use the thread-local resolver. */
+#ifdef DEBUG
+ asr_printf("using thread-local resolver\n");
+#endif
+ priv = _THREAD_PRIVATE(_asr, asr, &_asr);
+ if (*priv == NULL) {
+#ifdef DEBUG
+ asr_printf("setting up thread-local resolver\n");
+#endif
+ *priv = async_resolver(NULL);
+ }
+ asr = *priv;
}
asr_check_reload(asr);