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.
--- a/src/thread/pthread/SDL_systhread.c Fri Nov 02 16:48:47 2012 -0400
+++ b/src/thread/pthread/SDL_systhread.c Sat Nov 03 12:06:27 2012 -0400
@@ -28,21 +28,19 @@
#endif
#include <signal.h>
+
#ifdef __LINUX__
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <unistd.h>
-
-#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 <dlfcn.h>
+#ifndef RTLD_DEFAULT
+#define RTLD_DEFAULT NULL
+#endif
#endif
#include "SDL_platform.h"
@@ -53,6 +51,8 @@
#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 @@
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 @@
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 */