On Mon, Jan 04, 2021 at 06:03:46PM +0100, Mark Kettenis wrote: > > Date: Sun, 3 Jan 2021 13:47:45 +0100 > > From: Otto Moerbeek <o...@drijf.net> > > > > On Thu, Dec 31, 2020 at 05:54:06PM +0100, Alexander Bluhm wrote: > > > > > On Tue, Dec 29, 2020 at 04:07:19PM +0100, Otto Moerbeek wrote: > > > > This workds better, checking the flags does not work if the thread is > > > > already on the road to desctruction. > > > > > > This diff survived a full regress run on amd64. > > > > > > bluhm > > > > anybody wants to ok? > > Don't forget the debug leftovers (char buf[100] and int len). > > Also, is the #include <unistd.h> in thread/rthread_cb.c really needed?
nope, that was part of the debug code. > > Otherwise, this is ok kettenis@ > > > > > > 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 29 Dec 2020 15:05:45 -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: 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 29 Dec 2020 15:05:45 -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 29 Dec 2020 15:05:45 -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 29 Dec 2020 15:05:45 -0000 > > > > @@ -5,6 +5,8 @@ > > > > #include <pthread.h> > > > > #include <stdlib.h> > > > > #include <string.h> > > > > +#include <tib.h> > > > > +#include <unistd.h> > > > > > > > > #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; > > > > } > > > > > > >