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

> 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;
>                       }

Reply via email to