Mercurial > sdl-ios-xcode
annotate src/thread/linux/SDL_systhread.c @ 753:b14fdadd8311
Date: Thu, 4 Dec 2003 07:48:40 +0200
From: "Mike Gorchak"
Subject: SDL/QNX6 new patch
Here in attachment my patch for the SDL/QNX6 again :) It contain non-crtitical/cosmetic fixes:
1. Fixed window centering at other than the first consoles.
2. Fixed window centering algorithm in case when window height or width are greater than the desktop resolution.
3. Fixed window positioning on other than the first consoles.
4. Fixed occasional input focus lost when switching to fullscreen.
5. Removed the Photon's default chroma color for the overlays, added RGB(12, 6, 12) color instead (very dark pink).
6. Added more checks to the YUV overlay code (fixed crashes during resolution mode switches).
7. Added support for Enter/Backspace keys in unicode mode (used by Maelstrom and by other games).
8. Fixed window restore/maximize function. It works, finally.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 10 Dec 2003 12:35:56 +0000 |
parents | f6ffac90895c |
children | b8d311d90021 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
0 | 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 | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Linux thread management routines for SDL */ | |
29 | |
30 #include "SDL_error.h" | |
31 #include "SDL_thread.h" | |
32 #include "SDL_systhread.h" | |
33 | |
34 #ifdef FORK_HACK | |
35 | |
36 #include <unistd.h> | |
37 | |
38 int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) | |
39 { | |
40 SDL_SetError("Threads are not supported on this platform"); | |
41 return(-1); | |
42 } | |
43 void SDL_SYS_SetupThread(void) | |
44 { | |
45 return; | |
46 } | |
47 Uint32 SDL_ThreadID(void) | |
48 { | |
49 return((Uint32)getpid()); | |
50 } | |
51 void SDL_SYS_WaitThread(SDL_Thread *thread) | |
52 { | |
53 return; | |
54 } | |
55 void SDL_SYS_KillThread(SDL_Thread *thread) | |
56 { | |
57 return; | |
58 } | |
59 | |
60 #else | |
61 | |
62 #include <signal.h> | |
63 | |
64 #if !defined(MACOSX) /* pthread_sigmask seems to be missing on MacOS X? */ | |
65 /* List of signals to mask in the subthreads */ | |
66 static int sig_list[] = { | |
67 SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH, | |
68 SIGVTALRM, SIGPROF, 0 | |
69 }; | |
70 #endif /* !MACOSX */ | |
71 | |
72 #ifdef SDL_USE_PTHREADS | |
73 | |
74 #include <pthread.h> | |
75 | |
76 | |
77 static void *RunThread(void *data) | |
78 { | |
79 SDL_RunThread(data); | |
80 pthread_exit((void*)0); | |
81 return((void *)0); /* Prevent compiler warning */ | |
82 } | |
83 | |
84 int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) | |
85 { | |
86 pthread_attr_t type; | |
87 | |
88 /* Set the thread attributes */ | |
89 if ( pthread_attr_init(&type) != 0 ) { | |
90 SDL_SetError("Couldn't initialize pthread attributes"); | |
91 return(-1); | |
92 } | |
93 pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE); | |
94 | |
95 /* Create the thread and go! */ | |
96 if ( pthread_create(&thread->handle, &type, RunThread, args) != 0 ) { | |
97 SDL_SetError("Not enough resources to create thread"); | |
98 return(-1); | |
99 } | |
100 return(0); | |
101 } | |
102 | |
103 void SDL_SYS_SetupThread(void) | |
104 { | |
105 #if !defined(MACOSX) /* pthread_sigmask seems to be missing on MacOS X? */ | |
106 int i; | |
107 sigset_t mask; | |
108 | |
109 /* Mask asynchronous signals for this thread */ | |
110 sigemptyset(&mask); | |
111 for ( i=0; sig_list[i]; ++i ) { | |
112 sigaddset(&mask, sig_list[i]); | |
113 } | |
114 pthread_sigmask(SIG_BLOCK, &mask, 0); | |
115 #endif /* !MACOSX */ | |
116 | |
117 #ifdef PTHREAD_CANCEL_ASYNCHRONOUS | |
118 /* Allow ourselves to be asynchronously cancelled */ | |
119 { int oldstate; | |
120 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); | |
121 } | |
122 #endif | |
123 } | |
124 | |
125 /* WARNING: This may not work for systems with 64-bit pid_t */ | |
126 Uint32 SDL_ThreadID(void) | |
127 { | |
128 return((Uint32)pthread_self()); | |
129 } | |
130 | |
131 void SDL_SYS_WaitThread(SDL_Thread *thread) | |
132 { | |
133 pthread_join(thread->handle, 0); | |
134 } | |
135 | |
136 void SDL_SYS_KillThread(SDL_Thread *thread) | |
137 { | |
138 #ifdef PTHREAD_CANCEL_ASYNCHRONOUS | |
139 pthread_cancel(thread->handle); | |
140 #else | |
141 #ifdef __FreeBSD__ | |
142 #warning For some reason, this doesnt actually kill a thread - FreeBSD 3.2 | |
143 #endif | |
144 pthread_kill(thread->handle, SIGKILL); | |
145 #endif | |
146 } | |
147 | |
148 #else /* Linux-specific clone() based implementation */ | |
149 | |
150 #include <stdlib.h> | |
151 #include <errno.h> | |
152 #include <unistd.h> | |
153 #include <sys/wait.h> | |
154 | |
155 | |
156 /* Stack size for child thread */ | |
157 #define STACKSIZE 16384*4 /* 16384 is too small */ | |
158 | |
159 #ifdef __GLIBC__ | |
160 #include <sched.h> | |
161 #else | |
162 /* From <linux/sched.h> */ | |
163 #define CLONE_VM 0x00000100 /* set if VM shared */ | |
164 #define CLONE_FS 0x00000200 /* set if fs info shared */ | |
165 #define CLONE_FILES 0x00000400 /* set if open files shared */ | |
166 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */ | |
167 #define CLONE_PID 0x00001000 /* set if pid shared */ | |
168 | |
169 /* The infamous "start_thread" function, courtesy Linus Torvalds */ | |
170 extern int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); | |
171 #endif | |
172 | |
173 static int RunThread(void *data) | |
174 { | |
175 SDL_RunThread(data); | |
176 return(0); | |
177 } | |
178 | |
179 int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) | |
180 { | |
181 void *stack; | |
182 | |
183 /* Allocate memory for thread stack */ | |
184 stack = malloc(STACKSIZE); | |
185 if ( stack == (void *)0 ) { | |
186 SDL_OutOfMemory(); | |
187 return(-1); | |
188 } | |
189 thread->data = stack; | |
190 | |
191 /* Adjust the stack since it actually grows down */ | |
192 stack = (void *) ((char *)stack + STACKSIZE); | |
193 | |
194 /* Create the thread and go! */ | |
195 thread->handle = clone(RunThread, stack, | |
196 (CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND), args); | |
197 if ( thread->handle < 0 ) { | |
198 free(thread->data); | |
199 SDL_SetError("Not enough resources to create thread"); | |
200 return(-1); | |
201 } | |
202 return(0); | |
203 } | |
204 | |
205 void SDL_SYS_SetupThread(void) | |
206 { | |
207 int i; | |
208 sigset_t mask; | |
209 | |
210 /* Mask asynchronous signals for this thread */ | |
211 sigemptyset(&mask); | |
212 for ( i=0; sig_list[i]; ++i ) { | |
213 sigaddset(&mask, sig_list[i]); | |
214 } | |
215 sigprocmask(SIG_BLOCK, &mask, 0); | |
216 } | |
217 | |
218 /* WARNING: This may not work for systems with 64-bit pid_t */ | |
219 Uint32 SDL_ThreadID(void) | |
220 { | |
221 return((Uint32)getpid()); | |
222 } | |
223 | |
224 void SDL_SYS_WaitThread(SDL_Thread *thread) | |
225 { | |
226 #ifdef __WCLONE | |
227 errno = 0; | |
228 while ( errno != ECHILD ) { | |
229 waitpid(thread->handle, 0, __WCLONE); | |
230 } | |
231 #else | |
232 /* Ack, ugly ugly hack -- | |
233 wait() doesn't work, waitpid() doesn't work, and ignoring SIG_CHLD | |
234 doesn't work .. and the child thread is still a zombie, so kill() | |
235 doesn't work. | |
236 */ | |
237 char command[1024]; | |
238 | |
239 sprintf(command, | |
240 "ps ax|fgrep -v fgrep|fgrep -v '<zombie>'|fgrep %d >/dev/null", | |
241 thread->handle); | |
242 while ( system(command) == 0 ) | |
243 sleep(1); | |
244 #endif | |
245 free(thread->data); | |
246 } | |
247 | |
248 void SDL_SYS_KillThread(SDL_Thread *thread) | |
249 { | |
250 kill(thread->handle, SIGKILL); | |
251 } | |
252 | |
253 #endif /* SDL_USE_PTHREADS */ | |
254 | |
255 #endif /* FORK_HACK */ |