146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL - Simple DirectMedia Layer 346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Copyright (C) 1997-2006 Sam Lantinga 446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is free software; you can redistribute it and/or 646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner modify it under the terms of the GNU Lesser General Public 746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License as published by the Free Software Foundation; either 846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner version 2.1 of the License, or (at your option) any later version. 946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is distributed in the hope that it will be useful, 1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner but WITHOUT ANY WARRANTY; without even the implied warranty of 1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Lesser General Public License for more details. 1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You should have received a copy of the GNU Lesser General Public 1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License along with this library; if not, write to the Free Software 1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Sam Lantinga 2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner slouken@libsdl.org 2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h" 2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <pthread.h> 2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <signal.h> 2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_thread.h" 2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_thread_c.h" 2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_systhread.h" 3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* List of signals to mask in the subthreads */ 3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int sig_list[] = { 3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH, 3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SIGVTALRM, SIGPROF, 0 3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}; 3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef __RISCOS__ 3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* RISC OS needs to know the main thread for 3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * it's timer and event processing. */ 4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint riscos_using_threads = 0; 4146be48730333120a7b939116cef075e61c12c703David 'Digit' TurnerUint32 riscos_main_thread = 0; /* Thread running events */ 4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void *RunThread(void *data) 4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_RunThread(data); 4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pthread_exit((void*)0); 4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return((void *)0); /* Prevent compiler warning */ 5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SYS_CreateThread(SDL_Thread *thread, void *args) 5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pthread_attr_t type; 5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set the thread attributes */ 5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( pthread_attr_init(&type) != 0 ) { 5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Couldn't initialize pthread attributes"); 5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE); 6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Create the thread and go! */ 6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( pthread_create(&thread->handle, &type, RunThread, args) != 0 ) { 6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Not enough resources to create thread"); 6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef __RISCOS__ 7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (riscos_using_threads == 0) { 7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner riscos_using_threads = 1; 7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner riscos_main_thread = SDL_ThreadID(); 7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_SetupThread(void) 8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sigset_t mask; 8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Mask asynchronous signals for this thread */ 8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sigemptyset(&mask); 8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; sig_list[i]; ++i ) { 8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sigaddset(&mask, sig_list[i]); 8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pthread_sigmask(SIG_BLOCK, &mask, 0); 9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef PTHREAD_CANCEL_ASYNCHRONOUS 9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Allow ourselves to be asynchronously cancelled */ 9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { int oldstate; 9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); 9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* WARNING: This may not work for systems with 64-bit pid_t */ 10046be48730333120a7b939116cef075e61c12c703David 'Digit' TurnerUint32 SDL_ThreadID(void) 10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return((Uint32)pthread_self()); 10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_WaitThread(SDL_Thread *thread) 10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pthread_join(thread->handle, 0); 10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_KillThread(SDL_Thread *thread) 11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef PTHREAD_CANCEL_ASYNCHRONOUS 11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pthread_cancel(thread->handle); 11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#else 11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef __FREEBSD__ 11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#warning For some reason, this doesnt actually kill a thread - FreeBSD 3.2 11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pthread_kill(thread->handle, SIGKILL); 11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 121