Index: lib/libc/asr/asr.c =================================================================== RCS file: /mount/openbsd/cvs/src/lib/libc/asr/asr.c,v retrieving revision 1.64 diff -u -p -u -p -r1.64 asr.c --- lib/libc/asr/asr.c 6 Jul 2020 13:33:05 -0000 1.64 +++ lib/libc/asr/asr.c 30 Dec 2020 12:59:37 -0000 @@ -117,7 +117,7 @@ _asr_resolver_done(void *arg) _asr_ctx_unref(ac); return; } else { - priv = _THREAD_PRIVATE(_asr, _asr, &_asr); + priv = _THREAD_PRIVATE_DT(_asr, _asr, NULL, &_asr); if (*priv == NULL) return; asr = *priv; @@ -128,6 +128,23 @@ _asr_resolver_done(void *arg) free(asr); } +static void +_asr_resolver_done_tp(void *arg) +{ + char buf[100]; + int len; + struct asr **priv = arg; + struct asr *asr; + + if (*priv == NULL) + return; + asr = *priv; + + _asr_ctx_unref(asr->a_ctx); + free(asr); + free(priv); +} + void * asr_resolver_from_string(const char *str) { @@ -349,7 +366,8 @@ _asr_use_resolver(void *arg) } else { DPRINT("using thread-local resolver\n"); - priv = _THREAD_PRIVATE(_asr, _asr, &_asr); + priv = _THREAD_PRIVATE_DT(_asr, _asr, _asr_resolver_done_tp, + &_asr); if (*priv == NULL) { DPRINT("setting up thread-local resolver\n"); *priv = _asr_resolver(); Index: lib/libc/include/thread_private.h =================================================================== RCS file: /mount/openbsd/cvs/src/lib/libc/include/thread_private.h,v retrieving revision 1.35 diff -u -p -u -p -r1.35 thread_private.h --- lib/libc/include/thread_private.h 13 Feb 2019 13:22:14 -0000 1.35 +++ lib/libc/include/thread_private.h 30 Dec 2020 12:59:37 -0000 @@ -98,7 +98,8 @@ struct thread_callbacks { void (*tc_mutex_destroy)(void **); void (*tc_tag_lock)(void **); void (*tc_tag_unlock)(void **); - void *(*tc_tag_storage)(void **, void *, size_t, void *); + void *(*tc_tag_storage)(void **, void *, size_t, void (*)(void *), + void *); __pid_t (*tc_fork)(void); __pid_t (*tc_vfork)(void); void (*tc_thread_release)(struct pthread *); @@ -142,6 +143,7 @@ __END_HIDDEN_DECLS #define _THREAD_PRIVATE_MUTEX_LOCK(name) do {} while (0) #define _THREAD_PRIVATE_MUTEX_UNLOCK(name) do {} while (0) #define _THREAD_PRIVATE(keyname, storage, error) &(storage) +#define _THREAD_PRIVATE_DT(keyname, storage, dt, error) &(storage) #define _MUTEX_LOCK(mutex) do {} while (0) #define _MUTEX_UNLOCK(mutex) do {} while (0) #define _MUTEX_DESTROY(mutex) do {} while (0) @@ -168,7 +170,12 @@ __END_HIDDEN_DECLS #define _THREAD_PRIVATE(keyname, storage, error) \ (_thread_cb.tc_tag_storage == NULL ? &(storage) : \ _thread_cb.tc_tag_storage(&(__THREAD_NAME(keyname)), \ - &(storage), sizeof(storage), error)) + &(storage), sizeof(storage), NULL, (error))) + +#define _THREAD_PRIVATE_DT(keyname, storage, dt, error) \ + (_thread_cb.tc_tag_storage == NULL ? &(storage) : \ + _thread_cb.tc_tag_storage(&(__THREAD_NAME(keyname)), \ + &(storage), sizeof(storage), (dt), (error))) /* * Macros used in libc to access mutexes. Index: lib/libc/thread/rthread_cb.h =================================================================== RCS file: /mount/openbsd/cvs/src/lib/libc/thread/rthread_cb.h,v retrieving revision 1.2 diff -u -p -u -p -r1.2 rthread_cb.h --- lib/libc/thread/rthread_cb.h 5 Sep 2017 02:40:54 -0000 1.2 +++ lib/libc/thread/rthread_cb.h 30 Dec 2020 12:59:37 -0000 @@ -35,5 +35,5 @@ void _thread_mutex_unlock(void **); void _thread_mutex_destroy(void **); void _thread_tag_lock(void **); void _thread_tag_unlock(void **); -void *_thread_tag_storage(void **, void *, size_t, void *); +void *_thread_tag_storage(void **, void *, size_t, void (*)(void*), void *); __END_HIDDEN_DECLS Index: lib/libc/thread/rthread_libc.c =================================================================== RCS file: /mount/openbsd/cvs/src/lib/libc/thread/rthread_libc.c,v retrieving revision 1.3 diff -u -p -u -p -r1.3 rthread_libc.c --- lib/libc/thread/rthread_libc.c 10 Jan 2019 18:45:33 -0000 1.3 +++ lib/libc/thread/rthread_libc.c 30 Dec 2020 12:59:37 -0000 @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "rthread.h" #include "rthread_cb.h" @@ -31,7 +33,7 @@ static pthread_mutex_t _thread_tag_mutex * This function will never return NULL. */ static void -_thread_tag_init(void **tag) +_thread_tag_init(void **tag, void (*dt)(void *)) { struct _thread_tag *tt; int result; @@ -42,7 +44,8 @@ _thread_tag_init(void **tag) tt = malloc(sizeof *tt); if (tt != NULL) { result = pthread_mutex_init(&tt->m, NULL); - result |= pthread_key_create(&tt->k, free); + result |= pthread_key_create(&tt->k, dt ? dt : + free); *tag = tt; } } @@ -62,7 +65,7 @@ _thread_tag_lock(void **tag) if (__isthreaded) { if (*tag == NULL) - _thread_tag_init(tag); + _thread_tag_init(tag, NULL); tt = *tag; if (pthread_mutex_lock(&tt->m) != 0) _rthread_debug(1, "tag mutex lock failure"); @@ -79,7 +82,7 @@ _thread_tag_unlock(void **tag) if (__isthreaded) { if (*tag == NULL) - _thread_tag_init(tag); + _thread_tag_init(tag, NULL); tt = *tag; if (pthread_mutex_unlock(&tt->m) != 0) _rthread_debug(1, "tag mutex unlock failure"); @@ -88,28 +91,33 @@ _thread_tag_unlock(void **tag) /* * return the thread specific data for the given tag. If there - * is no data for this thread initialize it from 'storage'. + * is no data for this thread allocate and initialize it from 'storage' + * or clear it for non-main threads. * On any error return 'err'. */ void * -_thread_tag_storage(void **tag, void *storage, size_t sz, void *err) +_thread_tag_storage(void **tag, void * storage, size_t sz, void (*dt)(void *), + void *err) { struct _thread_tag *tt; void *ret; if (*tag == NULL) - _thread_tag_init(tag); + _thread_tag_init(tag, dt); tt = *tag; ret = pthread_getspecific(tt->k); if (ret == NULL) { - ret = malloc(sz); + ret = calloc(1, sz); if (ret == NULL) ret = err; else { - if (pthread_setspecific(tt->k, ret) == 0) - memcpy(ret, storage, sz); - else { + int len; + char buf[100]; + if (pthread_setspecific(tt->k, ret) == 0) { + if (pthread_self() == &_initial_thread) + memcpy(ret, storage, sz); + } else { free(ret); ret = err; }