Mercurial > SDL_sound_CoreAudio
comparison SDL_sound.c @ 219:ca3483f4cfec
Error message management now keeps state per-thread, and does not use
SDL_[GS]etError anymore, so SDL errors are not interfered with.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sun, 13 Jan 2002 21:51:57 +0000 |
parents | 07d0939d40e7 |
children | 249186e31431 |
comparison
equal
deleted
inserted
replaced
218:cbd5e308f12d | 219:ca3483f4cfec |
---|---|
158 | 158 |
159 | 159 |
160 | 160 |
161 /* General SDL_sound state ... */ | 161 /* General SDL_sound state ... */ |
162 | 162 |
163 static int initialized = 0; | 163 typedef struct __SOUND_ERRMSGTYPE__ |
164 { | |
165 Uint32 tid; | |
166 int errorAvailable; | |
167 char errorString[128]; | |
168 struct __SOUND_ERRMSGTYPE__ *next; | |
169 } ErrMsg; | |
170 | |
171 static ErrMsg *errorMessages = NULL; | |
172 static SDL_mutex *errorlist_mutex = NULL; | |
173 | |
174 /* !!! FIXME: This needs a mutex. */ | |
164 static Sound_Sample *samplesList = NULL; /* this is a linked list. */ | 175 static Sound_Sample *samplesList = NULL; /* this is a linked list. */ |
165 static const Sound_DecoderInfo **available_decoders = NULL; | 176 static const Sound_DecoderInfo **available_decoders = NULL; |
177 static int initialized = 0; | |
166 | 178 |
167 | 179 |
168 /* functions ... */ | 180 /* functions ... */ |
169 | 181 |
170 void Sound_GetLinkedVersion(Sound_Version *ver) | 182 void Sound_GetLinkedVersion(Sound_Version *ver) |
182 { | 194 { |
183 size_t i; | 195 size_t i; |
184 size_t pos = 0; | 196 size_t pos = 0; |
185 size_t total = sizeof (decoders) / sizeof (decoders[0]); | 197 size_t total = sizeof (decoders) / sizeof (decoders[0]); |
186 BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0); | 198 BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0); |
199 | |
187 samplesList = NULL; | 200 samplesList = NULL; |
201 errorMessages = NULL; | |
188 | 202 |
189 SDL_Init(SDL_INIT_AUDIO); | 203 SDL_Init(SDL_INIT_AUDIO); |
204 errorlist_mutex = SDL_CreateMutex(); | |
190 | 205 |
191 available_decoders = (const Sound_DecoderInfo **) | 206 available_decoders = (const Sound_DecoderInfo **) |
192 malloc((total) * sizeof (Sound_DecoderInfo *)); | 207 malloc((total) * sizeof (Sound_DecoderInfo *)); |
193 BAIL_IF_MACRO(available_decoders == NULL, ERR_OUT_OF_MEMORY, 0); | 208 BAIL_IF_MACRO(available_decoders == NULL, ERR_OUT_OF_MEMORY, 0); |
194 | 209 |
209 } /* Sound_Init */ | 224 } /* Sound_Init */ |
210 | 225 |
211 | 226 |
212 int Sound_Quit(void) | 227 int Sound_Quit(void) |
213 { | 228 { |
229 ErrMsg *err; | |
230 ErrMsg *nexterr = NULL; | |
214 size_t i; | 231 size_t i; |
215 | 232 |
216 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); | 233 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); |
217 | 234 |
218 while (((volatile Sound_Sample *) samplesList) != NULL) | 235 while (((volatile Sound_Sample *) samplesList) != NULL) |
219 Sound_FreeSample(samplesList); | 236 Sound_FreeSample(samplesList); |
237 | |
238 samplesList = NULL; | |
220 | 239 |
221 for (i = 0; decoders[i].funcs != NULL; i++) | 240 for (i = 0; decoders[i].funcs != NULL; i++) |
222 { | 241 { |
223 if (decoders[i].available) | 242 if (decoders[i].available) |
224 { | 243 { |
229 | 248 |
230 if (available_decoders != NULL) | 249 if (available_decoders != NULL) |
231 free((void *) available_decoders); | 250 free((void *) available_decoders); |
232 available_decoders = NULL; | 251 available_decoders = NULL; |
233 | 252 |
253 /* clean up error state for each thread... */ | |
254 SDL_LockMutex(errorlist_mutex); | |
255 for (err = errorMessages; err != NULL; err = nexterr) | |
256 { | |
257 nexterr = err->next; | |
258 free(err); | |
259 } /* for */ | |
260 SDL_UnlockMutex(errorlist_mutex); | |
261 SDL_DestroyMutex(errorlist_mutex); | |
262 errorMessages = NULL; | |
263 errorlist_mutex = NULL; | |
264 | |
234 initialized = 0; | 265 initialized = 0; |
235 | |
236 return(1); | 266 return(1); |
237 } /* Sound_Quit */ | 267 } /* Sound_Quit */ |
238 | 268 |
239 | 269 |
240 const Sound_DecoderInfo **Sound_AvailableDecoders(void) | 270 const Sound_DecoderInfo **Sound_AvailableDecoders(void) |
241 { | 271 { |
242 return(available_decoders); /* READ. ONLY. */ | 272 return(available_decoders); /* READ. ONLY. */ |
243 } /* Sound_AvailableDecoders */ | 273 } /* Sound_AvailableDecoders */ |
244 | 274 |
245 | 275 |
276 static ErrMsg *findErrorForCurrentThread(void) | |
277 { | |
278 ErrMsg *i; | |
279 Uint32 tid; | |
280 | |
281 if (errorMessages != NULL) | |
282 { | |
283 tid = SDL_ThreadID(); | |
284 | |
285 SDL_LockMutex(errorlist_mutex); | |
286 for (i = errorMessages; i != NULL; i = i->next) | |
287 { | |
288 if (i->tid == tid) | |
289 { | |
290 SDL_UnlockMutex(errorlist_mutex); | |
291 return(i); | |
292 } /* if */ | |
293 } /* for */ | |
294 SDL_UnlockMutex(errorlist_mutex); | |
295 } /* if */ | |
296 | |
297 return(NULL); /* no error available. */ | |
298 } /* findErrorForCurrentThread */ | |
299 | |
300 | |
246 const char *Sound_GetError(void) | 301 const char *Sound_GetError(void) |
247 { | 302 { |
248 return(SDL_GetError()); | 303 const char *retval = NULL; |
304 ErrMsg *err = findErrorForCurrentThread(); | |
305 if ((err != NULL) && (err->errorAvailable)) | |
306 { | |
307 retval = err->errorString; | |
308 err->errorAvailable = 0; | |
309 } /* if */ | |
310 | |
311 return(retval); | |
249 } /* Sound_GetError */ | 312 } /* Sound_GetError */ |
250 | 313 |
251 | 314 |
252 void Sound_ClearError(void) | 315 void Sound_ClearError(void) |
253 { | 316 { |
254 SDL_ClearError(); | 317 ErrMsg *err = findErrorForCurrentThread(); |
318 if (err != NULL) | |
319 err->errorAvailable = 0; | |
255 } /* Sound_ClearError */ | 320 } /* Sound_ClearError */ |
256 | 321 |
257 | 322 |
258 /* | 323 /* |
259 * This is declared in the internal header. | 324 * This is declared in the internal header. |
260 */ | 325 */ |
261 void Sound_SetError(const char *err) | 326 void Sound_SetError(const char *str) |
262 { | 327 { |
263 if (err != NULL) | 328 ErrMsg *err; |
264 { | 329 |
265 SNDDBG(("Sound_SetError(\"%s\");\n", err)); | 330 if (str == NULL) |
266 SDL_SetError(err); | 331 return; |
267 } /* if */ | 332 |
333 SNDDBG(("Sound_SetError(\"%s\");\n", str)); | |
334 | |
335 err = findErrorForCurrentThread(); | |
336 if (err == NULL) | |
337 { | |
338 err = (ErrMsg *) malloc(sizeof (ErrMsg)); | |
339 if (err == NULL) | |
340 return; /* uhh...? */ | |
341 | |
342 memset((void *) err, '\0', sizeof (ErrMsg)); | |
343 err->tid = SDL_ThreadID(); | |
344 | |
345 SDL_LockMutex(errorlist_mutex); | |
346 err->next = errorMessages; | |
347 errorMessages = err; | |
348 SDL_UnlockMutex(errorlist_mutex); | |
349 } /* if */ | |
350 | |
351 err->errorAvailable = 1; | |
352 strncpy(err->errorString, str, sizeof (err->errorString)); | |
353 err->errorString[sizeof (err->errorString) - 1] = '\0'; | |
268 } /* Sound_SetError */ | 354 } /* Sound_SetError */ |
269 | 355 |
270 | 356 |
271 /* | 357 /* |
272 * -ansi and -pedantic flags prevent use of strcasecmp() on Linux, and | 358 * -ansi and -pedantic flags prevent use of strcasecmp() on Linux, and |