diff options
Diffstat (limited to 'apps/plugins/sdl/src/thread/pthread')
-rw-r--r-- | apps/plugins/sdl/src/thread/pthread/SDL_syscond.c | 155 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/pthread/SDL_sysmutex.c | 153 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/pthread/SDL_sysmutex_c.h | 31 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/pthread/SDL_syssem.c | 190 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/pthread/SDL_systhread.c | 120 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/pthread/SDL_systhread_c.h | 26 |
6 files changed, 675 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/thread/pthread/SDL_syscond.c b/apps/plugins/sdl/src/thread/pthread/SDL_syscond.c new file mode 100644 index 0000000000..15bce96614 --- /dev/null +++ b/apps/plugins/sdl/src/thread/pthread/SDL_syscond.c | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <sys/time.h> | ||
25 | #include <unistd.h> | ||
26 | #include <errno.h> | ||
27 | #include <pthread.h> | ||
28 | |||
29 | #include "SDL_thread.h" | ||
30 | #include "SDL_sysmutex_c.h" | ||
31 | |||
32 | struct SDL_cond | ||
33 | { | ||
34 | pthread_cond_t cond; | ||
35 | }; | ||
36 | |||
37 | /* Create a condition variable */ | ||
38 | SDL_cond * SDL_CreateCond(void) | ||
39 | { | ||
40 | SDL_cond *cond; | ||
41 | |||
42 | cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); | ||
43 | if ( cond ) { | ||
44 | if ( pthread_cond_init(&cond->cond, NULL) < 0 ) { | ||
45 | SDL_SetError("pthread_cond_init() failed"); | ||
46 | SDL_free(cond); | ||
47 | cond = NULL; | ||
48 | } | ||
49 | } | ||
50 | return(cond); | ||
51 | } | ||
52 | |||
53 | /* Destroy a condition variable */ | ||
54 | void SDL_DestroyCond(SDL_cond *cond) | ||
55 | { | ||
56 | if ( cond ) { | ||
57 | pthread_cond_destroy(&cond->cond); | ||
58 | SDL_free(cond); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | /* Restart one of the threads that are waiting on the condition variable */ | ||
63 | int SDL_CondSignal(SDL_cond *cond) | ||
64 | { | ||
65 | int retval; | ||
66 | |||
67 | if ( ! cond ) { | ||
68 | SDL_SetError("Passed a NULL condition variable"); | ||
69 | return -1; | ||
70 | } | ||
71 | |||
72 | retval = 0; | ||
73 | if ( pthread_cond_signal(&cond->cond) != 0 ) { | ||
74 | SDL_SetError("pthread_cond_signal() failed"); | ||
75 | retval = -1; | ||
76 | } | ||
77 | return retval; | ||
78 | } | ||
79 | |||
80 | /* Restart all threads that are waiting on the condition variable */ | ||
81 | int SDL_CondBroadcast(SDL_cond *cond) | ||
82 | { | ||
83 | int retval; | ||
84 | |||
85 | if ( ! cond ) { | ||
86 | SDL_SetError("Passed a NULL condition variable"); | ||
87 | return -1; | ||
88 | } | ||
89 | |||
90 | retval = 0; | ||
91 | if ( pthread_cond_broadcast(&cond->cond) != 0 ) { | ||
92 | SDL_SetError("pthread_cond_broadcast() failed"); | ||
93 | retval = -1; | ||
94 | } | ||
95 | return retval; | ||
96 | } | ||
97 | |||
98 | int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) | ||
99 | { | ||
100 | int retval; | ||
101 | struct timeval delta; | ||
102 | struct timespec abstime; | ||
103 | |||
104 | if ( ! cond ) { | ||
105 | SDL_SetError("Passed a NULL condition variable"); | ||
106 | return -1; | ||
107 | } | ||
108 | |||
109 | gettimeofday(&delta, NULL); | ||
110 | |||
111 | abstime.tv_sec = delta.tv_sec + (ms/1000); | ||
112 | abstime.tv_nsec = (delta.tv_usec + (ms%1000) * 1000) * 1000; | ||
113 | if ( abstime.tv_nsec > 1000000000 ) { | ||
114 | abstime.tv_sec += 1; | ||
115 | abstime.tv_nsec -= 1000000000; | ||
116 | } | ||
117 | |||
118 | tryagain: | ||
119 | retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime); | ||
120 | switch (retval) { | ||
121 | case EINTR: | ||
122 | goto tryagain; | ||
123 | break; | ||
124 | case ETIMEDOUT: | ||
125 | retval = SDL_MUTEX_TIMEDOUT; | ||
126 | break; | ||
127 | case 0: | ||
128 | break; | ||
129 | default: | ||
130 | SDL_SetError("pthread_cond_timedwait() failed"); | ||
131 | retval = -1; | ||
132 | break; | ||
133 | } | ||
134 | return retval; | ||
135 | } | ||
136 | |||
137 | /* Wait on the condition variable, unlocking the provided mutex. | ||
138 | The mutex must be locked before entering this function! | ||
139 | */ | ||
140 | int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) | ||
141 | { | ||
142 | int retval; | ||
143 | |||
144 | if ( ! cond ) { | ||
145 | SDL_SetError("Passed a NULL condition variable"); | ||
146 | return -1; | ||
147 | } | ||
148 | |||
149 | retval = 0; | ||
150 | if ( pthread_cond_wait(&cond->cond, &mutex->id) != 0 ) { | ||
151 | SDL_SetError("pthread_cond_wait() failed"); | ||
152 | retval = -1; | ||
153 | } | ||
154 | return retval; | ||
155 | } | ||
diff --git a/apps/plugins/sdl/src/thread/pthread/SDL_sysmutex.c b/apps/plugins/sdl/src/thread/pthread/SDL_sysmutex.c new file mode 100644 index 0000000000..c3b8ce2c37 --- /dev/null +++ b/apps/plugins/sdl/src/thread/pthread/SDL_sysmutex.c | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <pthread.h> | ||
25 | |||
26 | #include "SDL_thread.h" | ||
27 | |||
28 | #if !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX && \ | ||
29 | !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP | ||
30 | #define FAKE_RECURSIVE_MUTEX | ||
31 | #endif | ||
32 | |||
33 | struct SDL_mutex { | ||
34 | pthread_mutex_t id; | ||
35 | #if FAKE_RECURSIVE_MUTEX | ||
36 | int recursive; | ||
37 | pthread_t owner; | ||
38 | #endif | ||
39 | }; | ||
40 | |||
41 | SDL_mutex *SDL_CreateMutex (void) | ||
42 | { | ||
43 | SDL_mutex *mutex; | ||
44 | pthread_mutexattr_t attr; | ||
45 | |||
46 | /* Allocate the structure */ | ||
47 | mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex)); | ||
48 | if ( mutex ) { | ||
49 | pthread_mutexattr_init(&attr); | ||
50 | #if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX | ||
51 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | ||
52 | #elif SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP | ||
53 | pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP); | ||
54 | #else | ||
55 | /* No extra attributes necessary */ | ||
56 | #endif | ||
57 | if ( pthread_mutex_init(&mutex->id, &attr) != 0 ) { | ||
58 | SDL_SetError("pthread_mutex_init() failed"); | ||
59 | SDL_free(mutex); | ||
60 | mutex = NULL; | ||
61 | } | ||
62 | } else { | ||
63 | SDL_OutOfMemory(); | ||
64 | } | ||
65 | return(mutex); | ||
66 | } | ||
67 | |||
68 | void SDL_DestroyMutex(SDL_mutex *mutex) | ||
69 | { | ||
70 | if ( mutex ) { | ||
71 | pthread_mutex_destroy(&mutex->id); | ||
72 | SDL_free(mutex); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | /* Lock the mutex */ | ||
77 | int SDL_mutexP(SDL_mutex *mutex) | ||
78 | { | ||
79 | int retval; | ||
80 | #if FAKE_RECURSIVE_MUTEX | ||
81 | pthread_t this_thread; | ||
82 | #endif | ||
83 | |||
84 | if ( mutex == NULL ) { | ||
85 | SDL_SetError("Passed a NULL mutex"); | ||
86 | return -1; | ||
87 | } | ||
88 | |||
89 | retval = 0; | ||
90 | #if FAKE_RECURSIVE_MUTEX | ||
91 | this_thread = pthread_self(); | ||
92 | if ( mutex->owner == this_thread ) { | ||
93 | ++mutex->recursive; | ||
94 | } else { | ||
95 | /* The order of operations is important. | ||
96 | We set the locking thread id after we obtain the lock | ||
97 | so unlocks from other threads will fail. | ||
98 | */ | ||
99 | if ( pthread_mutex_lock(&mutex->id) == 0 ) { | ||
100 | mutex->owner = this_thread; | ||
101 | mutex->recursive = 0; | ||
102 | } else { | ||
103 | SDL_SetError("pthread_mutex_lock() failed"); | ||
104 | retval = -1; | ||
105 | } | ||
106 | } | ||
107 | #else | ||
108 | if ( pthread_mutex_lock(&mutex->id) < 0 ) { | ||
109 | SDL_SetError("pthread_mutex_lock() failed"); | ||
110 | retval = -1; | ||
111 | } | ||
112 | #endif | ||
113 | return retval; | ||
114 | } | ||
115 | |||
116 | int SDL_mutexV(SDL_mutex *mutex) | ||
117 | { | ||
118 | int retval; | ||
119 | |||
120 | if ( mutex == NULL ) { | ||
121 | SDL_SetError("Passed a NULL mutex"); | ||
122 | return -1; | ||
123 | } | ||
124 | |||
125 | retval = 0; | ||
126 | #if FAKE_RECURSIVE_MUTEX | ||
127 | /* We can only unlock the mutex if we own it */ | ||
128 | if ( pthread_self() == mutex->owner ) { | ||
129 | if ( mutex->recursive ) { | ||
130 | --mutex->recursive; | ||
131 | } else { | ||
132 | /* The order of operations is important. | ||
133 | First reset the owner so another thread doesn't lock | ||
134 | the mutex and set the ownership before we reset it, | ||
135 | then release the lock semaphore. | ||
136 | */ | ||
137 | mutex->owner = 0; | ||
138 | pthread_mutex_unlock(&mutex->id); | ||
139 | } | ||
140 | } else { | ||
141 | SDL_SetError("mutex not owned by this thread"); | ||
142 | retval = -1; | ||
143 | } | ||
144 | |||
145 | #else | ||
146 | if ( pthread_mutex_unlock(&mutex->id) < 0 ) { | ||
147 | SDL_SetError("pthread_mutex_unlock() failed"); | ||
148 | retval = -1; | ||
149 | } | ||
150 | #endif /* FAKE_RECURSIVE_MUTEX */ | ||
151 | |||
152 | return retval; | ||
153 | } | ||
diff --git a/apps/plugins/sdl/src/thread/pthread/SDL_sysmutex_c.h b/apps/plugins/sdl/src/thread/pthread/SDL_sysmutex_c.h new file mode 100644 index 0000000000..5258890156 --- /dev/null +++ b/apps/plugins/sdl/src/thread/pthread/SDL_sysmutex_c.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_mutex_c_h | ||
25 | #define _SDL_mutex_c_h | ||
26 | |||
27 | struct SDL_mutex { | ||
28 | pthread_mutex_t id; | ||
29 | }; | ||
30 | |||
31 | #endif /* _SDL_mutex_c_h */ | ||
diff --git a/apps/plugins/sdl/src/thread/pthread/SDL_syssem.c b/apps/plugins/sdl/src/thread/pthread/SDL_syssem.c new file mode 100644 index 0000000000..a03870fa35 --- /dev/null +++ b/apps/plugins/sdl/src/thread/pthread/SDL_syssem.c | |||
@@ -0,0 +1,190 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <pthread.h> | ||
25 | #include <semaphore.h> | ||
26 | #include <errno.h> | ||
27 | #include <sys/time.h> | ||
28 | |||
29 | #include "SDL_thread.h" | ||
30 | #include "SDL_timer.h" | ||
31 | |||
32 | /* Wrapper around POSIX 1003.1b semaphores */ | ||
33 | |||
34 | #ifdef __MACOSX__ | ||
35 | /* Mac OS X doesn't support sem_getvalue() as of version 10.4 */ | ||
36 | #include "../generic/SDL_syssem.c" | ||
37 | #else | ||
38 | |||
39 | struct SDL_semaphore { | ||
40 | sem_t sem; | ||
41 | }; | ||
42 | |||
43 | /* Create a semaphore, initialized with value */ | ||
44 | SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) | ||
45 | { | ||
46 | SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem)); | ||
47 | if ( sem ) { | ||
48 | if ( sem_init(&sem->sem, 0, initial_value) < 0 ) { | ||
49 | SDL_SetError("sem_init() failed"); | ||
50 | SDL_free(sem); | ||
51 | sem = NULL; | ||
52 | } | ||
53 | } else { | ||
54 | SDL_OutOfMemory(); | ||
55 | } | ||
56 | return sem; | ||
57 | } | ||
58 | |||
59 | void SDL_DestroySemaphore(SDL_sem *sem) | ||
60 | { | ||
61 | if ( sem ) { | ||
62 | sem_destroy(&sem->sem); | ||
63 | SDL_free(sem); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | int SDL_SemTryWait(SDL_sem *sem) | ||
68 | { | ||
69 | int retval; | ||
70 | |||
71 | if ( ! sem ) { | ||
72 | SDL_SetError("Passed a NULL semaphore"); | ||
73 | return -1; | ||
74 | } | ||
75 | retval = SDL_MUTEX_TIMEDOUT; | ||
76 | if ( sem_trywait(&sem->sem) == 0 ) { | ||
77 | retval = 0; | ||
78 | } | ||
79 | return retval; | ||
80 | } | ||
81 | |||
82 | int SDL_SemWait(SDL_sem *sem) | ||
83 | { | ||
84 | int retval; | ||
85 | |||
86 | if ( ! sem ) { | ||
87 | SDL_SetError("Passed a NULL semaphore"); | ||
88 | return -1; | ||
89 | } | ||
90 | |||
91 | while ( ((retval = sem_wait(&sem->sem)) == -1) && (errno == EINTR) ) {} | ||
92 | if ( retval < 0 ) { | ||
93 | SDL_SetError("sem_wait() failed"); | ||
94 | } | ||
95 | return retval; | ||
96 | } | ||
97 | |||
98 | int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) | ||
99 | { | ||
100 | int retval; | ||
101 | #ifdef HAVE_SEM_TIMEDWAIT | ||
102 | struct timeval now; | ||
103 | struct timespec ts_timeout; | ||
104 | #else | ||
105 | Uint32 end; | ||
106 | #endif | ||
107 | |||
108 | if ( ! sem ) { | ||
109 | SDL_SetError("Passed a NULL semaphore"); | ||
110 | return -1; | ||
111 | } | ||
112 | |||
113 | /* Try the easy cases first */ | ||
114 | if ( timeout == 0 ) { | ||
115 | return SDL_SemTryWait(sem); | ||
116 | } | ||
117 | if ( timeout == SDL_MUTEX_MAXWAIT ) { | ||
118 | return SDL_SemWait(sem); | ||
119 | } | ||
120 | |||
121 | #ifdef HAVE_SEM_TIMEDWAIT | ||
122 | /* Setup the timeout. sem_timedwait doesn't wait for | ||
123 | * a lapse of time, but until we reach a certain time. | ||
124 | * This time is now plus the timeout. | ||
125 | */ | ||
126 | gettimeofday(&now, NULL); | ||
127 | |||
128 | /* Add our timeout to current time */ | ||
129 | now.tv_usec += (timeout % 1000) * 1000; | ||
130 | now.tv_sec += timeout / 1000; | ||
131 | |||
132 | /* Wrap the second if needed */ | ||
133 | if ( now.tv_usec >= 1000000 ) { | ||
134 | now.tv_usec -= 1000000; | ||
135 | now.tv_sec ++; | ||
136 | } | ||
137 | |||
138 | /* Convert to timespec */ | ||
139 | ts_timeout.tv_sec = now.tv_sec; | ||
140 | ts_timeout.tv_nsec = now.tv_usec * 1000; | ||
141 | |||
142 | /* Wait. */ | ||
143 | do | ||
144 | retval = sem_timedwait(&sem->sem, &ts_timeout); | ||
145 | while (retval == -1 && errno == EINTR); | ||
146 | |||
147 | if (retval == -1) | ||
148 | SDL_SetError(strerror(errno)); | ||
149 | #else | ||
150 | end = SDL_GetTicks() + timeout; | ||
151 | while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) { | ||
152 | if ((SDL_GetTicks() - end) >= 0) { | ||
153 | break; | ||
154 | } | ||
155 | SDL_Delay(0); | ||
156 | } | ||
157 | #endif /* HAVE_SEM_TIMEDWAIT */ | ||
158 | |||
159 | return retval; | ||
160 | } | ||
161 | |||
162 | Uint32 SDL_SemValue(SDL_sem *sem) | ||
163 | { | ||
164 | int ret = 0; | ||
165 | if ( sem ) { | ||
166 | sem_getvalue(&sem->sem, &ret); | ||
167 | if ( ret < 0 ) { | ||
168 | ret = 0; | ||
169 | } | ||
170 | } | ||
171 | return (Uint32)ret; | ||
172 | } | ||
173 | |||
174 | int SDL_SemPost(SDL_sem *sem) | ||
175 | { | ||
176 | int retval; | ||
177 | |||
178 | if ( ! sem ) { | ||
179 | SDL_SetError("Passed a NULL semaphore"); | ||
180 | return -1; | ||
181 | } | ||
182 | |||
183 | retval = sem_post(&sem->sem); | ||
184 | if ( retval < 0 ) { | ||
185 | SDL_SetError("sem_post() failed"); | ||
186 | } | ||
187 | return retval; | ||
188 | } | ||
189 | |||
190 | #endif /* __MACOSX__ */ | ||
diff --git a/apps/plugins/sdl/src/thread/pthread/SDL_systhread.c b/apps/plugins/sdl/src/thread/pthread/SDL_systhread.c new file mode 100644 index 0000000000..40cc3b717d --- /dev/null +++ b/apps/plugins/sdl/src/thread/pthread/SDL_systhread.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <pthread.h> | ||
25 | #include <signal.h> | ||
26 | |||
27 | #include "SDL_thread.h" | ||
28 | #include "../SDL_thread_c.h" | ||
29 | #include "../SDL_systhread.h" | ||
30 | |||
31 | /* List of signals to mask in the subthreads */ | ||
32 | static int sig_list[] = { | ||
33 | SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH, | ||
34 | SIGVTALRM, SIGPROF, 0 | ||
35 | }; | ||
36 | |||
37 | #ifdef __RISCOS__ | ||
38 | /* RISC OS needs to know the main thread for | ||
39 | * it's timer and event processing. */ | ||
40 | int riscos_using_threads = 0; | ||
41 | Uint32 riscos_main_thread = 0; /* Thread running events */ | ||
42 | #endif | ||
43 | |||
44 | |||
45 | static void *RunThread(void *data) | ||
46 | { | ||
47 | SDL_RunThread(data); | ||
48 | pthread_exit((void*)0); | ||
49 | return((void *)0); /* Prevent compiler warning */ | ||
50 | } | ||
51 | |||
52 | int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) | ||
53 | { | ||
54 | pthread_attr_t type; | ||
55 | |||
56 | /* Set the thread attributes */ | ||
57 | if ( pthread_attr_init(&type) != 0 ) { | ||
58 | SDL_SetError("Couldn't initialize pthread attributes"); | ||
59 | return(-1); | ||
60 | } | ||
61 | pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE); | ||
62 | |||
63 | /* Create the thread and go! */ | ||
64 | if ( pthread_create(&thread->handle, &type, RunThread, args) != 0 ) { | ||
65 | SDL_SetError("Not enough resources to create thread"); | ||
66 | return(-1); | ||
67 | } | ||
68 | |||
69 | #ifdef __RISCOS__ | ||
70 | if (riscos_using_threads == 0) { | ||
71 | riscos_using_threads = 1; | ||
72 | riscos_main_thread = SDL_ThreadID(); | ||
73 | } | ||
74 | #endif | ||
75 | |||
76 | return(0); | ||
77 | } | ||
78 | |||
79 | void SDL_SYS_SetupThread(void) | ||
80 | { | ||
81 | int i; | ||
82 | sigset_t mask; | ||
83 | |||
84 | /* Mask asynchronous signals for this thread */ | ||
85 | sigemptyset(&mask); | ||
86 | for ( i=0; sig_list[i]; ++i ) { | ||
87 | sigaddset(&mask, sig_list[i]); | ||
88 | } | ||
89 | pthread_sigmask(SIG_BLOCK, &mask, 0); | ||
90 | |||
91 | #ifdef PTHREAD_CANCEL_ASYNCHRONOUS | ||
92 | /* Allow ourselves to be asynchronously cancelled */ | ||
93 | { int oldstate; | ||
94 | pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); | ||
95 | } | ||
96 | #endif | ||
97 | } | ||
98 | |||
99 | /* WARNING: This may not work for systems with 64-bit pid_t */ | ||
100 | Uint32 SDL_ThreadID(void) | ||
101 | { | ||
102 | return((Uint32)((size_t)pthread_self())); | ||
103 | } | ||
104 | |||
105 | void SDL_SYS_WaitThread(SDL_Thread *thread) | ||
106 | { | ||
107 | pthread_join(thread->handle, 0); | ||
108 | } | ||
109 | |||
110 | void SDL_SYS_KillThread(SDL_Thread *thread) | ||
111 | { | ||
112 | #ifdef PTHREAD_CANCEL_ASYNCHRONOUS | ||
113 | pthread_cancel(thread->handle); | ||
114 | #else | ||
115 | #ifdef __FREEBSD__ | ||
116 | #warning For some reason, this doesnt actually kill a thread - FreeBSD 3.2 | ||
117 | #endif | ||
118 | pthread_kill(thread->handle, SIGKILL); | ||
119 | #endif | ||
120 | } | ||
diff --git a/apps/plugins/sdl/src/thread/pthread/SDL_systhread_c.h b/apps/plugins/sdl/src/thread/pthread/SDL_systhread_c.h new file mode 100644 index 0000000000..33ed750ff2 --- /dev/null +++ b/apps/plugins/sdl/src/thread/pthread/SDL_systhread_c.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <pthread.h> | ||
25 | |||
26 | typedef pthread_t SYS_ThreadHandle; | ||