Make Linux dynamically look up pthread_setname_np() for older glibc compat.
authorRyan C. Gordon <icculus@icculus.org>
Sat, 03 Nov 2012 12:06:27 -0400
changeset 664044a2e00e7c66
parent 6639 c7e81fae23c4
child 6641 45187a87d35b
Make Linux dynamically look up pthread_setname_np() for older glibc compat.

Cleaned up the lookup code to make Mac OS X use most of the same code.
src/thread/pthread/SDL_systhread.c
     1.1 --- a/src/thread/pthread/SDL_systhread.c	Fri Nov 02 16:48:47 2012 -0400
     1.2 +++ b/src/thread/pthread/SDL_systhread.c	Sat Nov 03 12:06:27 2012 -0400
     1.3 @@ -28,21 +28,19 @@
     1.4  #endif
     1.5  
     1.6  #include <signal.h>
     1.7 +
     1.8  #ifdef __LINUX__
     1.9  #include <sys/time.h>
    1.10  #include <sys/resource.h>
    1.11  #include <sys/syscall.h>
    1.12  #include <unistd.h>
    1.13 -
    1.14 -#if HAVE_PTHREAD_SETNAME_NP
    1.15 -extern int pthread_setname_np (pthread_t __target_thread, __const char *__name) __THROW __nonnull ((2));
    1.16 -#endif
    1.17  #endif // __LINUX__
    1.18  
    1.19 -#if ( (__MACOSX__ && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)) || \
    1.20 -      (__IPHONEOS__ && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)) )
    1.21 -#define NEED_DYNAMIC_PTHREAD_SETNAME_NP
    1.22 +#if defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)
    1.23  #include <dlfcn.h>
    1.24 +#ifndef RTLD_DEFAULT
    1.25 +#define RTLD_DEFAULT NULL
    1.26 +#endif
    1.27  #endif
    1.28  
    1.29  #include "SDL_platform.h"
    1.30 @@ -53,6 +51,8 @@
    1.31  #include "../../core/android/SDL_android.h"
    1.32  #endif
    1.33  
    1.34 +#include "SDL_assert.h"
    1.35 +
    1.36  /* List of signals to mask in the subthreads */
    1.37  static const int sig_list[] = {
    1.38      SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
    1.39 @@ -70,11 +70,31 @@
    1.40      return NULL;
    1.41  }
    1.42  
    1.43 +#if defined(__MACOSX__) || defined(__IPHONEOS__)
    1.44 +static SDL_bool checked_setname = SDL_FALSE;
    1.45 +static int (*pthread_setname_np)(const char*) = NULL;
    1.46 +#elif defined(__LINUX__)
    1.47 +static SDL_bool checked_setname = SDL_FALSE;
    1.48 +static int (*pthread_setname_np)(pthread_t, const char*) = NULL;
    1.49 +#endif
    1.50  int
    1.51  SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
    1.52  {
    1.53      pthread_attr_t type;
    1.54  
    1.55 +    /* do this here before any threads exist, so there's no race condition. */
    1.56 +    #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
    1.57 +    if (!checked_setname) {
    1.58 +        void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np");
    1.59 +        #if defined(__MACOSX__) || defined(__IPHONEOS__)
    1.60 +        pthread_setname_np = (int(*)(const char*)) fn;
    1.61 +        #elif defined(__LINUX__)
    1.62 +        pthread_setname_np = (int(*)(pthread_t, const char*)) fn;
    1.63 +        #endif
    1.64 +        checked_setname = SDL_TRUE;
    1.65 +    }
    1.66 +    #endif
    1.67 +
    1.68      /* Set the thread attributes */
    1.69      if (pthread_attr_init(&type) != 0) {
    1.70          SDL_SetError("Couldn't initialize pthread attributes");
    1.71 @@ -98,16 +118,20 @@
    1.72      sigset_t mask;
    1.73  
    1.74      if (name != NULL) {
    1.75 -#ifdef NEED_DYNAMIC_PTHREAD_SETNAME_NP
    1.76 -        int (*dynamic_pthread_setname_np)(const char*);
    1.77 -        *(void**)(&dynamic_pthread_setname_np) = dlsym(RTLD_DEFAULT, "pthread_setname_np");
    1.78 -        if ( dynamic_pthread_setname_np )
    1.79 -            dynamic_pthread_setname_np( name );
    1.80 -#elif HAVE_PTHREAD_SETNAME_NP
    1.81 -        pthread_setname_np(pthread_self(), name);
    1.82 -#elif HAVE_PTHREAD_SET_NAME_NP
    1.83 -        pthread_set_name_np(pthread_self(), name);
    1.84 -#endif
    1.85 +        #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
    1.86 +        SDL_assert(checked_setname);
    1.87 +        if (pthread_setname_np) {
    1.88 +            #if defined(__MACOSX__) || defined(__IPHONEOS__)
    1.89 +            pthread_setname_np(name);
    1.90 +            #elif defined(__LINUX__)
    1.91 +            pthread_setname_np(pthread_self(), name);
    1.92 +            #endif
    1.93 +        }
    1.94 +        #elif HAVE_PTHREAD_SETNAME_NP
    1.95 +            pthread_setname_np(pthread_self(), name);
    1.96 +        #elif HAVE_PTHREAD_SET_NAME_NP
    1.97 +            pthread_set_name_np(pthread_self(), name);
    1.98 +        #endif
    1.99      }
   1.100  
   1.101      /* Mask asynchronous signals for this thread */