From 37fab69bd35a7a9b09379d94e0551091089ef468 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 3 Nov 2012 12:06:27 -0400 Subject: [PATCH] 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 | 58 +++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c index 196ffda62..e772fff5f 100644 --- a/src/thread/pthread/SDL_systhread.c +++ b/src/thread/pthread/SDL_systhread.c @@ -28,21 +28,19 @@ #endif #include + #ifdef __LINUX__ #include #include #include #include - -#if HAVE_PTHREAD_SETNAME_NP -extern int pthread_setname_np (pthread_t __target_thread, __const char *__name) __THROW __nonnull ((2)); -#endif #endif // __LINUX__ -#if ( (__MACOSX__ && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)) || \ - (__IPHONEOS__ && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)) ) -#define NEED_DYNAMIC_PTHREAD_SETNAME_NP +#if defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__) #include +#ifndef RTLD_DEFAULT +#define RTLD_DEFAULT NULL +#endif #endif #include "SDL_platform.h" @@ -53,6 +51,8 @@ extern int pthread_setname_np (pthread_t __target_thread, __const char *__name) #include "../../core/android/SDL_android.h" #endif +#include "SDL_assert.h" + /* List of signals to mask in the subthreads */ static const int sig_list[] = { SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH, @@ -70,11 +70,31 @@ RunThread(void *data) return NULL; } +#if defined(__MACOSX__) || defined(__IPHONEOS__) +static SDL_bool checked_setname = SDL_FALSE; +static int (*pthread_setname_np)(const char*) = NULL; +#elif defined(__LINUX__) +static SDL_bool checked_setname = SDL_FALSE; +static int (*pthread_setname_np)(pthread_t, const char*) = NULL; +#endif int SDL_SYS_CreateThread(SDL_Thread * thread, void *args) { pthread_attr_t type; + /* do this here before any threads exist, so there's no race condition. */ + #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) + if (!checked_setname) { + void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np"); + #if defined(__MACOSX__) || defined(__IPHONEOS__) + pthread_setname_np = (int(*)(const char*)) fn; + #elif defined(__LINUX__) + pthread_setname_np = (int(*)(pthread_t, const char*)) fn; + #endif + checked_setname = SDL_TRUE; + } + #endif + /* Set the thread attributes */ if (pthread_attr_init(&type) != 0) { SDL_SetError("Couldn't initialize pthread attributes"); @@ -98,16 +118,20 @@ SDL_SYS_SetupThread(const char *name) sigset_t mask; if (name != NULL) { -#ifdef NEED_DYNAMIC_PTHREAD_SETNAME_NP - int (*dynamic_pthread_setname_np)(const char*); - *(void**)(&dynamic_pthread_setname_np) = dlsym(RTLD_DEFAULT, "pthread_setname_np"); - if ( dynamic_pthread_setname_np ) - dynamic_pthread_setname_np( name ); -#elif HAVE_PTHREAD_SETNAME_NP - pthread_setname_np(pthread_self(), name); -#elif HAVE_PTHREAD_SET_NAME_NP - pthread_set_name_np(pthread_self(), name); -#endif + #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) + SDL_assert(checked_setname); + if (pthread_setname_np) { + #if defined(__MACOSX__) || defined(__IPHONEOS__) + pthread_setname_np(name); + #elif defined(__LINUX__) + pthread_setname_np(pthread_self(), name); + #endif + } + #elif HAVE_PTHREAD_SETNAME_NP + pthread_setname_np(pthread_self(), name); + #elif HAVE_PTHREAD_SET_NAME_NP + pthread_set_name_np(pthread_self(), name); + #endif } /* Mask asynchronous signals for this thread */