From 29bb8ec546cfa313c6a94d3669d408029effb566 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 27 Sep 2011 23:14:16 -0400 Subject: [PATCH 1/9] ============================================================ --- src/video/x11/SDL_x11touch.c | 92 ++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/src/video/x11/SDL_x11touch.c b/src/video/x11/SDL_x11touch.c index 4b4702a77..9f245ad93 100644 --- a/src/video/x11/SDL_x11touch.c +++ b/src/video/x11/SDL_x11touch.c @@ -38,7 +38,7 @@ X11_InitTouch(_THIS) #ifdef SDL_INPUT_LINUXEV FILE *fd; fd = fopen("/proc/bus/input/devices","r"); - + char c; int i = 0; char line[256]; @@ -47,46 +47,44 @@ X11_InitTouch(_THIS) while(!feof(fd)) { if(fgets(line,256,fd) <=0) continue; if(line[0] == '\n') { - if(vendor == 1386 || vendor==1){ - - sprintf(tstr,"/dev/input/event%i",event); - - SDL_Touch touch; - touch.pressure_max = 0; - touch.pressure_min = 0; - touch.id = event; - - - touch.driverdata = SDL_malloc(sizeof(EventTouchData)); - EventTouchData* data = (EventTouchData*)(touch.driverdata); - - data->x = -1; - data->y = -1; - data->pressure = -1; - data->finger = 0; - data->up = SDL_FALSE; - data->down = SDL_FALSE; - - - data->eventStream = open(tstr, - O_RDONLY | O_NONBLOCK); - ioctl (data->eventStream, EVIOCGNAME (sizeof (tstr)), tstr); - - int abs[5]; - ioctl(data->eventStream,EVIOCGABS(0),abs); - touch.x_min = abs[1]; - touch.x_max = abs[2]; - touch.native_xres = touch.x_max - touch.x_min; - ioctl(data->eventStream,EVIOCGABS(ABS_Y),abs); - touch.y_min = abs[1]; - touch.y_max = abs[2]; - touch.native_yres = touch.y_max - touch.y_min; - ioctl(data->eventStream,EVIOCGABS(ABS_PRESSURE),abs); - touch.pressure_min = abs[1]; - touch.pressure_max = abs[2]; - touch.native_pressureres = touch.pressure_max - touch.pressure_min; - - SDL_AddTouch(&touch, tstr); + if(vendor == 1386 || vendor==1) { + + sprintf(tstr,"/dev/input/event%i",event); + + SDL_Touch touch; + touch.pressure_max = 0; + touch.pressure_min = 0; + touch.id = event; + + touch.driverdata = SDL_malloc(sizeof(EventTouchData)); + EventTouchData* data = (EventTouchData*)(touch.driverdata); + + data->x = -1; + data->y = -1; + data->pressure = -1; + data->finger = 0; + data->up = SDL_FALSE; + data->down = SDL_FALSE; + + data->eventStream = open(tstr, + O_RDONLY | O_NONBLOCK); + ioctl (data->eventStream, EVIOCGNAME (sizeof (tstr)), tstr); + + int abs[5]; + ioctl(data->eventStream,EVIOCGABS(0),abs); + touch.x_min = abs[1]; + touch.x_max = abs[2]; + touch.native_xres = touch.x_max - touch.x_min; + ioctl(data->eventStream,EVIOCGABS(ABS_Y),abs); + touch.y_min = abs[1]; + touch.y_max = abs[2]; + touch.native_yres = touch.y_max - touch.y_min; + ioctl(data->eventStream,EVIOCGABS(ABS_PRESSURE),abs); + touch.pressure_min = abs[1]; + touch.pressure_max = abs[2]; + touch.native_pressureres = touch.pressure_max - touch.pressure_min; + + SDL_AddTouch(&touch, tstr); } vendor = -1; product = -1; @@ -95,20 +93,20 @@ X11_InitTouch(_THIS) else if(line[0] == 'I') { i = 1; while(line[i]) { - sscanf(&line[i],"Vendor=%x",&vendor); - sscanf(&line[i],"Product=%x",&product); - i++; + sscanf(&line[i],"Vendor=%x",&vendor); + sscanf(&line[i],"Product=%x",&product); + i++; } } else if(line[0] == 'H') { i = 1; while(line[i]) { - sscanf(&line[i],"event%d",&event); - i++; + sscanf(&line[i],"event%d",&event); + i++; } } } - + close(fd); #endif } From e3ad0bef7ad96da41215753e3c4b489d7463ba15 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 27 Sep 2011 23:15:01 -0400 Subject: [PATCH 2/9] ============================================================ --- src/video/x11/SDL_x11touch.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/video/x11/SDL_x11touch.c b/src/video/x11/SDL_x11touch.c index 9f245ad93..adc16ce04 100644 --- a/src/video/x11/SDL_x11touch.c +++ b/src/video/x11/SDL_x11touch.c @@ -51,6 +51,10 @@ X11_InitTouch(_THIS) sprintf(tstr,"/dev/input/event%i",event); + int tsfd = open( tstr, O_RDONLY | O_NONBLOCK ); + if ( tsfd == -1 ) + continue; /* Maybe not enough permissions ? */ + SDL_Touch touch; touch.pressure_max = 0; touch.pressure_min = 0; @@ -66,8 +70,7 @@ X11_InitTouch(_THIS) data->up = SDL_FALSE; data->down = SDL_FALSE; - data->eventStream = open(tstr, - O_RDONLY | O_NONBLOCK); + data->eventStream = tsfd; ioctl (data->eventStream, EVIOCGNAME (sizeof (tstr)), tstr); int abs[5]; From 8d8032130bd523f55725bb8ddd0678a88775aee2 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 27 Sep 2011 23:16:04 -0400 Subject: [PATCH 3/9] Fixed to compile with pedantic C --- src/video/x11/SDL_x11touch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/x11/SDL_x11touch.c b/src/video/x11/SDL_x11touch.c index adc16ce04..327648d7b 100644 --- a/src/video/x11/SDL_x11touch.c +++ b/src/video/x11/SDL_x11touch.c @@ -41,6 +41,7 @@ X11_InitTouch(_THIS) char c; int i = 0; + int tsfd; char line[256]; char tstr[256]; int vendor = -1,product = -1,event = -1; @@ -51,7 +52,7 @@ X11_InitTouch(_THIS) sprintf(tstr,"/dev/input/event%i",event); - int tsfd = open( tstr, O_RDONLY | O_NONBLOCK ); + tsfd = open( tstr, O_RDONLY | O_NONBLOCK ); if ( tsfd == -1 ) continue; /* Maybe not enough permissions ? */ From 1772c81a7d438c5d1235cf6ffdc7e1935d956c26 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 2 Oct 2011 00:29:16 -0400 Subject: [PATCH 4/9] 1.3 API CHANGE: Add support for naming threads. --- configure.in | 24 +++++++++++++++++ include/SDL_config.h.in | 3 +++ include/SDL_thread.h | 32 ++++++++++++++++++++--- src/audio/SDL_audio.c | 6 +++-- src/main/beos/SDL_BeApp.cc | 2 +- src/thread/SDL_systhread.h | 2 +- src/thread/SDL_thread.c | 42 +++++++++++++++++++++--------- src/thread/SDL_thread_c.h | 1 + src/thread/beos/SDL_systhread.c | 10 +++++-- src/thread/generic/SDL_systhread.c | 2 +- src/thread/irix/SDL_systhread.c | 2 +- src/thread/nds/SDL_systhread.c | 2 +- src/thread/pthread/SDL_systhread.c | 23 +++++++++++++++- src/thread/windows/SDL_systhread.c | 32 +++++++++++++++++++++-- src/timer/SDL_timer.c | 5 ++-- test/testatomic.c | 12 ++++++--- test/testerror.c | 2 +- test/testlock.c | 4 ++- test/testsem.c | 4 ++- test/testthread.c | 4 +-- test/threadwin.c | 4 +-- test/torturethread.c | 8 ++++-- 22 files changed, 182 insertions(+), 44 deletions(-) diff --git a/configure.in b/configure.in index 4f85cc4f7..09d11851b 100644 --- a/configure.in +++ b/configure.in @@ -1642,6 +1642,30 @@ AC_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]]) ]) AC_MSG_RESULT($has_pthread_spin_trylock) + AC_CHECK_HEADER(pthread_np.h, have_pthread_np_h=yes) + if test x$have_pthread_np_h = xyes; then + AC_DEFINE(HAVE_PTHREAD_NP_H, 1, [ ]) + fi + + # Check to see if pthread naming is available + AC_MSG_CHECKING(for pthread_setname_np) + AC_TRY_LINK_FUNC(pthread_setname_np, [ + has_pthread_setname_np=yes + AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [ ]) + ],[ + has_pthread_setname_np=no + ]) + AC_MSG_RESULT($has_pthread_setname_np) + + AC_MSG_CHECKING(for pthread_set_name_np) + AC_TRY_LINK_FUNC(pthread_set_name_np, [ + has_pthread_set_name_np=yes + AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [ ]) + ],[ + has_pthread_set_name_np=no + ]) + AC_MSG_RESULT($has_pthread_set_name_np) + # Restore the compiler flags and libraries CFLAGS="$ac_save_cflags"; LIBS="$ac_save_libs" diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 5808aeeb8..60aade2c4 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -69,6 +69,7 @@ #undef HAVE_ICONV_H #undef HAVE_SIGNAL_H #undef HAVE_ALTIVEC_H +#undef HAVE_PTHREAD_NP_H /* C library functions */ #undef HAVE_MALLOC @@ -148,6 +149,8 @@ #undef HAVE_GETPAGESIZE #undef HAVE_MPROTECT #undef HAVE_ICONV +#undef HAVE_PTHREAD_SETNAME_NP +#undef HAVE_PTHREAD_SET_NAME_NP #else /* We may need some replacement for stdarg.h here */ diff --git a/include/SDL_thread.h b/include/SDL_thread.h index 238ed3d43..49b8b22ff 100644 --- a/include/SDL_thread.h +++ b/include/SDL_thread.h @@ -102,7 +102,7 @@ typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); * Create a thread. */ extern DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(SDL_ThreadFunction fn, void *data, +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); @@ -111,26 +111,50 @@ SDL_CreateThread(SDL_ThreadFunction fn, void *data, /** * Create a thread. */ -#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, NULL, NULL) +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, NULL, NULL) #else /** * Create a thread. */ -#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthreadex, _endthreadex) +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, _beginthreadex, _endthreadex) #endif #else /** * Create a thread. + * + * Thread naming is a little complicated: Most systems have very small + * limits for the string length (BeOS has 32 bytes, Linux currently has 16, + * Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You'll + * have to see what happens with your system's debugger. The name should be + * UTF-8 (but using the naming limits of C identifiers is a better bet). + * There are no requirements for thread naming conventions, so long as the + * string is null-terminated UTF-8, but these guidelines are helpful in + * choosing a name: + * + * http://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * If a system imposes requirements, SDL will try to munge the string for + * it (truncate, etc), but the original string contents will be available + * from SDL_GetThreadName(). */ extern DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(SDL_ThreadFunction fn, void *data); +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data); #endif +/** + * Get the thread name, as it was specified in SDL_CreateThread(). + * This function returns a pointer to a UTF-8 string that names the + * specified thread, or NULL if it doesn't have a name. This is internal + * memory, not to be free()'d by the caller, and remains valid until the + * specified thread is cleaned up by SDL_WaitThread(). + */ +extern DECLSPEC const char *SDLCALL SDL_GetThreadName(SDL_Thread *thread); + /** * Get the thread identifier for the current thread. */ diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 7fb5d2422..a50f3937b 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -1033,12 +1033,14 @@ open_audio_device(const char *devname, int iscapture, /* Start the audio thread if necessary */ if (!current_audio.impl.ProvidesOwnCallbackThread) { /* Start the audio thread */ + char name[64]; + SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) (id + 1)); /* !!! FIXME: this is nasty. */ #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) #undef SDL_CreateThread - device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL); + device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL); #else - device->thread = SDL_CreateThread(SDL_RunAudio, device); + device->thread = SDL_CreateThread(SDL_RunAudio, name, device); #endif if (device->thread == NULL) { SDL_CloseAudioDevice(id + 1); diff --git a/src/main/beos/SDL_BeApp.cc b/src/main/beos/SDL_BeApp.cc index f54d55cd2..07632f39d 100644 --- a/src/main/beos/SDL_BeApp.cc +++ b/src/main/beos/SDL_BeApp.cc @@ -60,7 +60,7 @@ SDL_InitBeApp(void) { /* Create the BApplication that handles appserver interaction */ if (SDL_BeAppActive <= 0) { - SDL_AppThread = SDL_CreateThread(StartBeApp, NULL); + SDL_AppThread = SDL_CreateThread(StartBeApp, "SDLApplication", NULL); if (SDL_AppThread == NULL) { SDL_SetError("Couldn't create BApplication thread"); return (-1); diff --git a/src/thread/SDL_systhread.h b/src/thread/SDL_systhread.h index 30499b9e2..6e4dba77b 100644 --- a/src/thread/SDL_systhread.h +++ b/src/thread/SDL_systhread.h @@ -40,7 +40,7 @@ extern int SDL_SYS_CreateThread(SDL_Thread * thread, void *args); #endif /* This function does any necessary setup in the child thread */ -extern void SDL_SYS_SetupThread(void); +extern void SDL_SYS_SetupThread(const char *name); /* This function sets the current thread priority */ extern int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority); diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index b9408d60b..a1144c176 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -188,25 +188,19 @@ typedef struct void SDL_RunThread(void *data) { - thread_args *args; - int (SDLCALL * userfunc) (void *); - void *userdata; - int *statusloc; + thread_args *args = (thread_args *) data; + int (SDLCALL * userfunc) (void *) = args->func; + void *userdata = args->data; + int *statusloc = &args->info->status; /* Perform any system-dependent setup - this function cannot fail, and cannot use SDL_SetError() */ - SDL_SYS_SetupThread(); + SDL_SYS_SetupThread(args->info->name); /* Get the thread id */ - args = (thread_args *) data; args->info->threadid = SDL_ThreadID(); - /* Figure out what function to run */ - userfunc = args->func; - userdata = args->data; - statusloc = &args->info->status; - /* Wake up the parent thread */ SDL_SemPost(args->wait); @@ -217,12 +211,14 @@ SDL_RunThread(void *data) #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD #undef SDL_CreateThread DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(int (SDLCALL * fn) (void *), void *data, +SDL_CreateThread(int (SDLCALL * fn) (void *), + const char *name, void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread) #else DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(int (SDLCALL * fn) (void *), void *data) +SDL_CreateThread(int (SDLCALL * fn) (void *), + const char *name, void *data) #endif { SDL_Thread *thread; @@ -238,10 +234,21 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), void *data) SDL_memset(thread, 0, (sizeof *thread)); thread->status = -1; + /* Set up the arguments for the thread */ + if (name != NULL) { + thread->name = SDL_strdup(name); + if (thread->name == NULL) { + SDL_OutOfMemory(); + SDL_free(thread); + return (NULL); + } + } + /* Set up the arguments for the thread */ args = (thread_args *) SDL_malloc(sizeof(*args)); if (args == NULL) { SDL_OutOfMemory(); + SDL_free(thread->name); SDL_free(thread); return (NULL); } @@ -250,6 +257,7 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), void *data) args->info = thread; args->wait = SDL_CreateSemaphore(0); if (args->wait == NULL) { + SDL_free(thread->name); SDL_free(thread); SDL_free(args); return (NULL); @@ -270,6 +278,7 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), void *data) } else { /* Oops, failed. Gotta free everything */ SDL_DelThread(thread); + SDL_free(thread->name); SDL_free(thread); thread = NULL; } @@ -293,6 +302,12 @@ SDL_GetThreadID(SDL_Thread * thread) return id; } +const char * +SDL_GetThreadName(SDL_Thread * thread) +{ + return thread->name; +} + int SDL_SetThreadPriority(SDL_ThreadPriority priority) { @@ -308,6 +323,7 @@ SDL_WaitThread(SDL_Thread * thread, int *status) *status = thread->status; } SDL_DelThread(thread); + SDL_free(thread->name); SDL_free(thread); } } diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index f369591a4..8474cfb0c 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -51,6 +51,7 @@ struct SDL_Thread SYS_ThreadHandle handle; int status; SDL_error errbuf; + char *name; void *data; }; diff --git a/src/thread/beos/SDL_systhread.c b/src/thread/beos/SDL_systhread.c index 5f49d8734..13e2db823 100644 --- a/src/thread/beos/SDL_systhread.c +++ b/src/thread/beos/SDL_systhread.c @@ -65,8 +65,13 @@ RunThread(void *data) int SDL_SYS_CreateThread(SDL_Thread * thread, void *args) { + /* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */ + char name[B_OS_NAME_LENGTH]; + SDL_snprintf(name, sizeof (name), "%s", thread->name); + name[sizeof (name) - 1] = '\0'; + /* Create the thread and go! */ - thread->handle = spawn_thread(RunThread, "SDL", B_NORMAL_PRIORITY, args); + thread->handle = spawn_thread(RunThread, name, B_NORMAL_PRIORITY, args); if ((thread->handle == B_NO_MORE_THREADS) || (thread->handle == B_NO_MEMORY)) { SDL_SetError("Not enough resources to create thread"); @@ -77,8 +82,9 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) } void -SDL_SYS_SetupThread(void) +SDL_SYS_SetupThread(const char *name) { + /* We set the thread name during SDL_SYS_CreateThread(). */ /* Mask asynchronous signals for this thread */ SDL_MaskSignals(NULL); } diff --git a/src/thread/generic/SDL_systhread.c b/src/thread/generic/SDL_systhread.c index ab0be8eea..ecab2909f 100644 --- a/src/thread/generic/SDL_systhread.c +++ b/src/thread/generic/SDL_systhread.c @@ -33,7 +33,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) } void -SDL_SYS_SetupThread(void) +SDL_SYS_SetupThread(const char *name) { return; } diff --git a/src/thread/irix/SDL_systhread.c b/src/thread/irix/SDL_systhread.c index 8fe087308..d2ed080d0 100644 --- a/src/thread/irix/SDL_systhread.c +++ b/src/thread/irix/SDL_systhread.c @@ -50,7 +50,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) } void -SDL_SYS_SetupThread(void) +SDL_SYS_SetupThread(const char *name) { int i; sigset_t mask; diff --git a/src/thread/nds/SDL_systhread.c b/src/thread/nds/SDL_systhread.c index bf473ec88..3bdebcee1 100644 --- a/src/thread/nds/SDL_systhread.c +++ b/src/thread/nds/SDL_systhread.c @@ -38,7 +38,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) } void -SDL_SYS_SetupThread(void) +SDL_SYS_SetupThread(const char *name) { return; } diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c index e795f000b..472aef864 100644 --- a/src/thread/pthread/SDL_systhread.c +++ b/src/thread/pthread/SDL_systhread.c @@ -21,6 +21,11 @@ #include "SDL_config.h" #include + +#if HAVE_PTHREAD_NP_H +#include +#endif + #include #ifdef __LINUX__ #include @@ -28,6 +33,7 @@ #include #endif +#include "SDL_platform.h" #include "SDL_thread.h" #include "../SDL_thread_c.h" #include "../SDL_systhread.h" @@ -67,12 +73,27 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) return (0); } +/* make pthread_setname_np() a weak reference even without SDK support. */ +#if __MACOSX__ && (MAC_OS_X_VERSION_MAX_ALLOWED < 1060) +int pthread_setname_np(const char*) __attribute__((weak_import,visibility("default"))); +#elif __IPHONEOS__ && (__IPHONE_OS_VERSION_MAX_ALLOWED < 30200) +int pthread_setname_np(const char*) __attribute__((weak_import)); +#endif + void -SDL_SYS_SetupThread(void) +SDL_SYS_SetupThread(const char *name) { int i; sigset_t mask; +#if __MACOSX__ || __IPHONEOS__ + if (pthread_setname_np != NULL) { 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 + /* Mask asynchronous signals for this thread */ sigemptyset(&mask); for (i = 0; sig_list[i]; ++i) { diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c index f4f1ca333..74a3ec6fd 100644 --- a/src/thread/windows/SDL_systhread.c +++ b/src/thread/windows/SDL_systhread.c @@ -146,10 +146,38 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) return (0); } +#ifdef _MSC_VER +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; /* must be 0x1000 */ + LPCSTR szName; /* pointer to name (in user addr space) */ + DWORD dwThreadID; /* thread ID (-1=caller thread) */ + DWORD dwFlags; /* reserved for future use, must be zero */ +} THREADNAME_INFO; +#pragma pack(pop) +#endif + void -SDL_SYS_SetupThread(void) +SDL_SYS_SetupThread(const char *name) { - return; +#ifdef _MSC_VER /* !!! FIXME: can we do SEH on other compilers yet? */ + /* This magic tells the debugger to name a thread if it's listening. */ + THREADNAME_INFO inf; + info.dwType = 0x1000; + info.szName = name; + info.dwThreadID = (DWORD) -1; + info.dwFlags = 0; + + __try + { + RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf); + } + except(EXCEPTION_CONTINUE_EXECUTION) + { + /* The program itself should ignore this bogus exception. */ + } +#endif } SDL_threadID diff --git a/src/timer/SDL_timer.c b/src/timer/SDL_timer.c index b7e9099a3..0d4ce20b5 100644 --- a/src/timer/SDL_timer.c +++ b/src/timer/SDL_timer.c @@ -209,6 +209,7 @@ SDL_TimerInit(void) SDL_TimerData *data = &SDL_timer_data; if (!data->active) { + const char *name = "SDLTimer"; data->timermap_lock = SDL_CreateMutex(); if (!data->timermap_lock) { return -1; @@ -224,9 +225,9 @@ SDL_TimerInit(void) /* !!! FIXME: this is nasty. */ #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) #undef SDL_CreateThread - data->thread = SDL_CreateThread(SDL_TimerThread, data, NULL, NULL); + data->thread = SDL_CreateThread(SDL_TimerThread, name, data, NULL, NULL); #else - data->thread = SDL_CreateThread(SDL_TimerThread, data); + data->thread = SDL_CreateThread(SDL_TimerThread, name, data); #endif if (!data->thread) { SDL_TimerQuit(); diff --git a/test/testatomic.c b/test/testatomic.c index 0af3030a0..a05834080 100644 --- a/test/testatomic.c +++ b/test/testatomic.c @@ -143,7 +143,7 @@ void runAdder(void) SDL_AtomicSet(&threadsRunning, NThreads); while (T--) - SDL_CreateThread(adder, NULL); + SDL_CreateThread(adder, "Adder", NULL); while (SDL_AtomicGet(&threadsRunning) > 0) SDL_SemWait(threadDone); @@ -618,7 +618,7 @@ static void RunFIFOTest(SDL_bool lock_free) #ifdef TEST_SPINLOCK_FIFO /* Start a monitoring thread */ if (lock_free) { - SDL_CreateThread(FIFO_Watcher, &queue); + SDL_CreateThread(FIFO_Watcher, "FIFOWatcher", &queue); } #endif @@ -627,9 +627,11 @@ static void RunFIFOTest(SDL_bool lock_free) SDL_zero(readerData); SDL_AtomicSet(&readersRunning, NUM_READERS); for (i = 0; i < NUM_READERS; ++i) { + char name[64]; + SDL_snprintf(name, sizeof (name), "FIFOReader%d", i); readerData[i].queue = &queue; readerData[i].lock_free = lock_free; - SDL_CreateThread(FIFO_Reader, &readerData[i]); + SDL_CreateThread(FIFO_Reader, name, &readerData[i]); } /* Start up the writers */ @@ -637,10 +639,12 @@ static void RunFIFOTest(SDL_bool lock_free) SDL_zero(writerData); SDL_AtomicSet(&writersRunning, NUM_WRITERS); for (i = 0; i < NUM_WRITERS; ++i) { + char name[64]; + SDL_snprintf(name, sizeof (name), "FIFOWriter%d", i); writerData[i].queue = &queue; writerData[i].index = i; writerData[i].lock_free = lock_free; - SDL_CreateThread(FIFO_Writer, &writerData[i]); + SDL_CreateThread(FIFO_Writer, name, &writerData[i]); } /* Wait for the writers */ diff --git a/test/testerror.c b/test/testerror.c index d2dfc4040..d96fcc59b 100644 --- a/test/testerror.c +++ b/test/testerror.c @@ -58,7 +58,7 @@ main(int argc, char *argv[]) SDL_SetError("No worries"); alive = 1; - thread = SDL_CreateThread(ThreadFunc, "#1"); + thread = SDL_CreateThread(ThreadFunc, NULL, "#1"); if (thread == NULL) { fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError()); quit(1); diff --git a/test/testlock.c b/test/testlock.c index b111343b1..362d687cf 100644 --- a/test/testlock.c +++ b/test/testlock.c @@ -112,7 +112,9 @@ main(int argc, char *argv[]) printf("Main thread: %lu\n", mainthread); atexit(printid); for (i = 0; i < maxproc; ++i) { - if ((threads[i] = SDL_CreateThread(Run, NULL)) == NULL) + char name[64]; + SDL_snprintf(name, sizeof (name), "Worker%d", i); + if ((threads[i] = SDL_CreateThread(Run, name, NULL)) == NULL) fprintf(stderr, "Couldn't create thread!\n"); } signal(SIGINT, terminate); diff --git a/test/testsem.c b/test/testsem.c index b75b4930d..62d15a6ac 100644 --- a/test/testsem.c +++ b/test/testsem.c @@ -100,7 +100,9 @@ main(int argc, char **argv) init_sem); /* Create all the threads */ for (i = 0; i < NUM_THREADS; ++i) { - threads[i] = SDL_CreateThread(ThreadFunc, (void *) i); + char name[64]; + SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i); + threads[i] = SDL_CreateThread(ThreadFunc, name, (void *) i); } /* Wait 10 seconds */ diff --git a/test/testthread.c b/test/testthread.c index dc2e2a09a..21509ff1d 100644 --- a/test/testthread.c +++ b/test/testthread.c @@ -63,7 +63,7 @@ main(int argc, char *argv[]) } alive = 1; - thread = SDL_CreateThread(ThreadFunc, "#1"); + thread = SDL_CreateThread(ThreadFunc, "One", "#1"); if (thread == NULL) { fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError()); quit(1); @@ -75,7 +75,7 @@ main(int argc, char *argv[]) alive = 1; signal(SIGTERM, killed); - thread = SDL_CreateThread(ThreadFunc, "#2"); + thread = SDL_CreateThread(ThreadFunc, "Two", "#2"); if (thread == NULL) { fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError()); quit(1); diff --git a/test/threadwin.c b/test/threadwin.c index cbdb716a0..1388cdc14 100644 --- a/test/threadwin.c +++ b/test/threadwin.c @@ -296,8 +296,8 @@ main(int argc, char *argv[]) SDL_SetEventFilter(FilterEvents, NULL); /* Create the event handling threads */ - mouse_thread = SDL_CreateThread(HandleMouse, NULL); - keybd_thread = SDL_CreateThread(HandleKeyboard, NULL); + mouse_thread = SDL_CreateThread(HandleMouse, "MouseHandler", NULL); + keybd_thread = SDL_CreateThread(HandleKeyboard, "KeyboardHandler", NULL); /* Set the surface pixels and refresh! */ for (i = 0; i < 256; ++i) { diff --git a/test/torturethread.c b/test/torturethread.c index 23396e70a..fb003d499 100644 --- a/test/torturethread.c +++ b/test/torturethread.c @@ -52,8 +52,10 @@ ThreadFunc(void *data) fprintf(stderr, "Creating Thread %d\n", tid); for (i = 0; i < NUMTHREADS; i++) { + char name[64]; + SDL_snprintf(name, sizeof (name), "Child%d_%d", tid, i); flags[i] = 0; - sub_threads[i] = SDL_CreateThread(SubThreadFunc, &flags[i]); + sub_threads[i] = SDL_CreateThread(SubThreadFunc, name, &flags[i]); } printf("Thread '%d' waiting for signal\n", tid); @@ -86,8 +88,10 @@ main(int argc, char *argv[]) signal(SIGSEGV, SIG_DFL); for (i = 0; i < NUMTHREADS; i++) { + char name[64]; + SDL_snprintf(name, sizeof (name), "Parent%d", i); time_for_threads_to_die[i] = 0; - threads[i] = SDL_CreateThread(ThreadFunc, (void *) (uintptr_t) i); + threads[i] = SDL_CreateThread(ThreadFunc, name, (void*) (uintptr_t) i); if (threads[i] == NULL) { fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError()); From baf91431fe34051a2e9117d760bd62bb37f21802 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 2 Oct 2011 00:36:18 -0400 Subject: [PATCH 5/9] Patched to compile on Windows. --- src/thread/windows/SDL_systhread.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c index 74a3ec6fd..3c7bbae0f 100644 --- a/src/thread/windows/SDL_systhread.c +++ b/src/thread/windows/SDL_systhread.c @@ -164,10 +164,10 @@ SDL_SYS_SetupThread(const char *name) #ifdef _MSC_VER /* !!! FIXME: can we do SEH on other compilers yet? */ /* This magic tells the debugger to name a thread if it's listening. */ THREADNAME_INFO inf; - info.dwType = 0x1000; - info.szName = name; - info.dwThreadID = (DWORD) -1; - info.dwFlags = 0; + inf.dwType = 0x1000; + inf.szName = name; + inf.dwThreadID = (DWORD) -1; + inf.dwFlags = 0; __try { From 9e4363738c9fa80e45f0c2c8e2d5eb114aebf760 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 2 Oct 2011 00:43:56 -0400 Subject: [PATCH 6/9] Further patched to compile on Windows. --- src/thread/windows/SDL_systhread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c index 3c7bbae0f..a1c1c2700 100644 --- a/src/thread/windows/SDL_systhread.c +++ b/src/thread/windows/SDL_systhread.c @@ -173,7 +173,7 @@ SDL_SYS_SetupThread(const char *name) { RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf); } - except(EXCEPTION_CONTINUE_EXECUTION) + __except(EXCEPTION_CONTINUE_EXECUTION) { /* The program itself should ignore this bogus exception. */ } From 4a0f4851ab0122ade7fe841d605776170f7bb3ee Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 2 Oct 2011 00:49:52 -0400 Subject: [PATCH 7/9] Patched to compile on Mac OS X (I think). --- src/thread/pthread/SDL_systhread.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c index 472aef864..334d33abc 100644 --- a/src/thread/pthread/SDL_systhread.c +++ b/src/thread/pthread/SDL_systhread.c @@ -73,20 +73,14 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) return (0); } -/* make pthread_setname_np() a weak reference even without SDK support. */ -#if __MACOSX__ && (MAC_OS_X_VERSION_MAX_ALLOWED < 1060) -int pthread_setname_np(const char*) __attribute__((weak_import,visibility("default"))); -#elif __IPHONEOS__ && (__IPHONE_OS_VERSION_MAX_ALLOWED < 30200) -int pthread_setname_np(const char*) __attribute__((weak_import)); -#endif - void SDL_SYS_SetupThread(const char *name) { int i; sigset_t mask; -#if __MACOSX__ || __IPHONEOS__ +#if ( (__MACOSX__ && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)) || \ + (__IPHONEOS__ && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)) ) if (pthread_setname_np != NULL) { pthread_setname_np(name); } #elif HAVE_PTHREAD_SETNAME_NP pthread_setname_np(pthread_self(), name); From 8d731813344ddedb309b010dcabe2c61a822dc64 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 2 Oct 2011 00:59:11 -0400 Subject: [PATCH 8/9] Disable thread naming on Windows for now. We need the C runtime, which we don't link against, for __try/__except. --- src/thread/windows/SDL_systhread.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c index a1c1c2700..e0bd3fbd1 100644 --- a/src/thread/windows/SDL_systhread.c +++ b/src/thread/windows/SDL_systhread.c @@ -161,6 +161,7 @@ typedef struct tagTHREADNAME_INFO void SDL_SYS_SetupThread(const char *name) { +#if 0 /* !!! FIXME: __except needs C runtime, which we don't link against. */ #ifdef _MSC_VER /* !!! FIXME: can we do SEH on other compilers yet? */ /* This magic tells the debugger to name a thread if it's listening. */ THREADNAME_INFO inf; @@ -178,6 +179,7 @@ SDL_SYS_SetupThread(const char *name) /* The program itself should ignore this bogus exception. */ } #endif +#endif } SDL_threadID From 2b282ec8ccafce14fc1a42f99686e8cb8be0062f Mon Sep 17 00:00:00 2001 From: Andreas Schiffler Date: Wed, 5 Oct 2011 08:08:06 -0700 Subject: [PATCH 9/9] Refactored audio device enumeration/naming tests ana added negative cases --- .../tests/testaudio/testaudio.c | 108 +++++++++++++----- 1 file changed, 77 insertions(+), 31 deletions(-) diff --git a/test/test-automation/tests/testaudio/testaudio.c b/test/test-automation/tests/testaudio/testaudio.c index fb025fc0a..511a78fe4 100644 --- a/test/test-automation/tests/testaudio/testaudio.c +++ b/test/test-automation/tests/testaudio/testaudio.c @@ -1,5 +1,6 @@ /** - * Original code: automated SDL rect test written by Edgar Simo "bobbens" + * Original code: automated SDL audio test written by Edgar Simo "bobbens" + * New/updated tests: aschiffler at ferzkopp dot net */ #include @@ -10,10 +11,10 @@ /* Test cases */ static const TestCaseReference test1 = - (TestCaseReference){ "audio_printOutputDevices", "Checks available output (non-capture) device names.", TEST_ENABLED, TEST_REQUIRES_AUDIO, 0}; + (TestCaseReference){ "audio_enumerateAndNameAudioDevices", "Enumerate and name available audio devices (output and capture)", TEST_ENABLED, TEST_REQUIRES_AUDIO, 0}; static const TestCaseReference test2 = - (TestCaseReference){ "audio_printInputDevices", "Checks available input (capture) device names.", TEST_ENABLED, TEST_REQUIRES_AUDIO, 0}; + (TestCaseReference){ "audio_enumerateAndNameAudioDevicesNegativeTests", "Netative tests around enumeration and naming of audio devices.", TEST_ENABLED, TEST_REQUIRES_AUDIO, 0}; static const TestCaseReference test3 = (TestCaseReference){ "audio_printAudioDrivers", "Checks available audio driver names.", TEST_ENABLED, TEST_REQUIRES_AUDIO, 0}; @@ -31,7 +32,7 @@ TestCaseReference **QueryTestSuite() { return (TestCaseReference **)testSuite; } -// Fixture +/* Fixture */ void SetUp(void *arg) @@ -51,49 +52,94 @@ TearDown(void *arg) /* Test case functions */ /** - * @brief Checks available output (non-capture) device names. + * \brief Enumerate and name available audio devices (output and capture). + * + * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDevices + * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDeviceName */ -int audio_printOutputDevices() +int audio_enumerateAndNameAudioDevices() { int ret; - int i, n; - const char *name; + int t, tt; + int i, n, nn; + const char *name, *nameAgain; - /* Get number of devices. */ - n = SDL_GetNumAudioDevices(0); - AssertTrue(n>=0, "Number of output devices < 0, reported as %i", n); + /* Iterate over types: t=0 output device, t=1 input/capture device */ + for (t=0; t<2; t++) { - /* List devices. */ - if (n>0) - { - for (i=0; i0, "name blank"); + /* Get number of devices. */ + n = SDL_GetNumAudioDevices(t); + AssertTrue(n>=0, + "Number of %s devices < 0, reported as %i: %s", + (t) ? "output" : "capture", + n, + SDL_GetError()); + + /* Variation of non-zero type */ + if (t==1) { + tt = t + RandomIntegerInRange(1,10); + nn = SDL_GetNumAudioDevices(tt); + AssertTrue(n==nn, "SDL_GetNumAudioDevices(%i) : expected same number of audio devices %i, got %i", tt, n, nn); + nn = SDL_GetNumAudioDevices(-tt); + AssertTrue(n==nn, "SDL_GetNumAudioDevices(%i) : expected same number of audio devices %i, got %i", -tt, n, nn); + } + + /* List devices. */ + if (n>0) { + for (i=0; i0, "SDL_GetAudioDeviceName(%i, %i): returned empty name string", i, t); + if (t==1) { + /* Also try non-zero type */ + nameAgain = SDL_GetAudioDeviceName(i, tt); + AssertTrue(nameAgain != NULL, "SDL_GetAudioDeviceName(%i, %i): returned NULL name", i, tt); + AssertTrue(strlen(nameAgain)>0, "SDL_GetAudioDeviceName(%i, %i): returned empty name string", i, tt); + AssertTrue(strcmp(name, nameAgain)==0, + "SDL_GetAudioDeviceName(%i, %i): returned unexpected name string %s, expected %s", + i, tt, nameAgain, name); + } + } } } } /** - * @brief Checks available input (capture) device names. + * \brief Negative tests around enumeration and naming of audio devices. + * + * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDevices + * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDeviceName */ -int audio_printInputDevices() +int audio_enumerateAndNameAudioDevicesNegativeTests() { int ret; - int i, n; + int t; + int i, j, no, nc; const char *name; - + /* Get number of devices. */ - n = SDL_GetNumAudioDevices(1); - AssertTrue(n>=0, "Number of input devices < 0, reported as %i", n); + no = SDL_GetNumAudioDevices(0); + nc = SDL_GetNumAudioDevices(1); - /* List devices. */ - if (n>0) - { - for (i=0; i0, "name empty"); + /* Invalid device index when getting name */ + for (t=0; t<2; t++) { + /* Negative device index */ + i = -1; + name = SDL_GetAudioDeviceName(i, t); + AssertTrue(name == NULL, "SDL_GetAudioDeviceName(%i, %i): returned a name, should return NULL", i, t); + + /* Device index past range */ + for (j=0; j<3; j++) { + i = (t) ? nc+j : no+j; + name = SDL_GetAudioDeviceName(i, t); + AssertTrue(name == NULL, "SDL_GetAudioDeviceName(%i, %i): returned a name, should return NULL", i, t); + } + + /* Capture index past capture range but within output range */ + if ((no>0) && (no>nc) && (t==1)) { + i = no-1; + name = SDL_GetAudioDeviceName(i, t); + AssertTrue(name == NULL, "SDL_GetAudioDeviceName(%i, %i): returned a name, should return NULL", i, t); } } }