Mercurial > sdl-ios-xcode
annotate src/thread/linux/SDL_systhread.c @ 1135:cf6133247d34
Mac Classic and CodeWarrior patches.
--ryan.
From: =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb@algonet.se>
Subject: Re: [SDL] Updated Mac patch
Date: Tue, 6 Sep 2005 15:21:27 +0200
To: A list for developers using the SDL library <sdl@libsdl.org>
Earlier, I wrote:
> Updated the previous Mac patch to disable Carbon by default.
> Also "fixed" the SDL.spec again, so that it builds on Darwin.
>
> http://www.algonet.se/~afb/SDL-1.2.9-mac.patch
> Also applied fine to SDL12 CVS, when I tried it.
>
> Haven't completed any new packaging or projects for Xcode/PB,
> but it seems to build and install fine here (in development).
Tested the new patch to build with old CodeWarrior and MPW,
and it seems it needed some hacks with those old headers...
Just in case you want to support the archeological versions -
here is a small add-on to the above patch, to fix those...
http://www.algonet.se/~afb/SDL-1.2.9-classic.patch
I couldn't get the old CW5 projects to build without a few
modifications - such as deleting the stray old header in:
"CWprojects/Support/Carbon/Include/ConditionalMacros.h" ?
But I updated both projects to CW6 too and built for Carbon,
and it ran all of the Mac test projects without any problems.
The MPW file seems to have compiled, with a small order change.
As long as you're still shipping the CWProjects and MPWmake
with the download, they should probably be updated/fixed ?
(another "solution" would of course be to just delete them)
I'll post my new projects along with the new Xcode projects
later on, along with XML exports of the various .mcp files.
(CW5 builds for Classic / "PPC", and CW6 builds for Carbon)
It'll be packaged as a part of the next SpriteWorld X release...
http://spriteworldx.sourceforge.net/ [Classic/Carbon/Win/X11]
--anders
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 08 Sep 2005 06:34:28 +0000 |
parents | b8d311d90021 |
children | fd068ab116ee |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
3 Copyright (C) 1997-2004 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 */ |