Hi, So here the diff that just fixes the mem leak on thread exit. It does not contains the TLS init part, I'd like to do that differently than what I did in the version I posted earlier.
As stated before, this makes the getaddrino(3) test program run in constant memory. ok? -Otto Index: asr/asr.c =================================================================== RCS file: /cvs/src/lib/libc/asr/asr.c,v retrieving revision 1.64 diff -u -p -r1.64 asr.c --- asr/asr.c 6 Jul 2020 13:33:05 -0000 1.64 +++ asr/asr.c 27 Dec 2020 19:44:01 -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,21 @@ _asr_resolver_done(void *arg) free(asr); } +static void +_asr_resolver_done_tp(void *arg) +{ + 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 +364,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: include/thread_private.h =================================================================== RCS file: /cvs/src/lib/libc/include/thread_private.h,v retrieving revision 1.35 diff -u -p -r1.35 thread_private.h --- include/thread_private.h 13 Feb 2019 13:22:14 -0000 1.35 +++ include/thread_private.h 27 Dec 2020 19:44:01 -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: thread/rthread_cb.h =================================================================== RCS file: /cvs/src/lib/libc/thread/rthread_cb.h,v retrieving revision 1.2 diff -u -p -r1.2 rthread_cb.h --- thread/rthread_cb.h 5 Sep 2017 02:40:54 -0000 1.2 +++ thread/rthread_cb.h 27 Dec 2020 19:44:01 -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: thread/rthread_libc.c =================================================================== RCS file: /cvs/src/lib/libc/thread/rthread_libc.c,v retrieving revision 1.3 diff -u -p -r1.3 rthread_libc.c --- thread/rthread_libc.c 10 Jan 2019 18:45:33 -0000 1.3 +++ thread/rthread_libc.c 27 Dec 2020 19:44:01 -0000 @@ -31,7 +31,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 +42,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 +63,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 +80,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"); @@ -92,13 +93,13 @@ _thread_tag_unlock(void **tag) * 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);