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