# HG changeset patch # User Ryan C. Gordon # Date 1010958717 0 # Node ID ca3483f4cfec5b8676260c98b3b2588623f2d201 # Parent cbd5e308f12d19feeb0404ec945ec7688bfdaf50 Error message management now keeps state per-thread, and does not use SDL_[GS]etError anymore, so SDL errors are not interfered with. diff -r cbd5e308f12d -r ca3483f4cfec SDL_sound.c --- a/SDL_sound.c Sun Jan 13 21:51:04 2002 +0000 +++ b/SDL_sound.c Sun Jan 13 21:51:57 2002 +0000 @@ -160,9 +160,21 @@ /* General SDL_sound state ... */ -static int initialized = 0; +typedef struct __SOUND_ERRMSGTYPE__ +{ + Uint32 tid; + int errorAvailable; + char errorString[128]; + struct __SOUND_ERRMSGTYPE__ *next; +} ErrMsg; + +static ErrMsg *errorMessages = NULL; +static SDL_mutex *errorlist_mutex = NULL; + +/* !!! FIXME: This needs a mutex. */ static Sound_Sample *samplesList = NULL; /* this is a linked list. */ static const Sound_DecoderInfo **available_decoders = NULL; +static int initialized = 0; /* functions ... */ @@ -184,9 +196,12 @@ size_t pos = 0; size_t total = sizeof (decoders) / sizeof (decoders[0]); BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0); + samplesList = NULL; + errorMessages = NULL; SDL_Init(SDL_INIT_AUDIO); + errorlist_mutex = SDL_CreateMutex(); available_decoders = (const Sound_DecoderInfo **) malloc((total) * sizeof (Sound_DecoderInfo *)); @@ -211,6 +226,8 @@ int Sound_Quit(void) { + ErrMsg *err; + ErrMsg *nexterr = NULL; size_t i; BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); @@ -218,6 +235,8 @@ while (((volatile Sound_Sample *) samplesList) != NULL) Sound_FreeSample(samplesList); + samplesList = NULL; + for (i = 0; decoders[i].funcs != NULL; i++) { if (decoders[i].available) @@ -231,8 +250,19 @@ free((void *) available_decoders); available_decoders = NULL; + /* clean up error state for each thread... */ + SDL_LockMutex(errorlist_mutex); + for (err = errorMessages; err != NULL; err = nexterr) + { + nexterr = err->next; + free(err); + } /* for */ + SDL_UnlockMutex(errorlist_mutex); + SDL_DestroyMutex(errorlist_mutex); + errorMessages = NULL; + errorlist_mutex = NULL; + initialized = 0; - return(1); } /* Sound_Quit */ @@ -243,28 +273,84 @@ } /* Sound_AvailableDecoders */ +static ErrMsg *findErrorForCurrentThread(void) +{ + ErrMsg *i; + Uint32 tid; + + if (errorMessages != NULL) + { + tid = SDL_ThreadID(); + + SDL_LockMutex(errorlist_mutex); + for (i = errorMessages; i != NULL; i = i->next) + { + if (i->tid == tid) + { + SDL_UnlockMutex(errorlist_mutex); + return(i); + } /* if */ + } /* for */ + SDL_UnlockMutex(errorlist_mutex); + } /* if */ + + return(NULL); /* no error available. */ +} /* findErrorForCurrentThread */ + + const char *Sound_GetError(void) { - return(SDL_GetError()); + const char *retval = NULL; + ErrMsg *err = findErrorForCurrentThread(); + if ((err != NULL) && (err->errorAvailable)) + { + retval = err->errorString; + err->errorAvailable = 0; + } /* if */ + + return(retval); } /* Sound_GetError */ void Sound_ClearError(void) { - SDL_ClearError(); + ErrMsg *err = findErrorForCurrentThread(); + if (err != NULL) + err->errorAvailable = 0; } /* Sound_ClearError */ /* * This is declared in the internal header. */ -void Sound_SetError(const char *err) +void Sound_SetError(const char *str) { - if (err != NULL) + ErrMsg *err; + + if (str == NULL) + return; + + SNDDBG(("Sound_SetError(\"%s\");\n", str)); + + err = findErrorForCurrentThread(); + if (err == NULL) { - SNDDBG(("Sound_SetError(\"%s\");\n", err)); - SDL_SetError(err); + err = (ErrMsg *) malloc(sizeof (ErrMsg)); + if (err == NULL) + return; /* uhh...? */ + + memset((void *) err, '\0', sizeof (ErrMsg)); + err->tid = SDL_ThreadID(); + + SDL_LockMutex(errorlist_mutex); + err->next = errorMessages; + errorMessages = err; + SDL_UnlockMutex(errorlist_mutex); } /* if */ + + err->errorAvailable = 1; + strncpy(err->errorString, str, sizeof (err->errorString)); + err->errorString[sizeof (err->errorString) - 1] = '\0'; } /* Sound_SetError */