Mercurial > almixer_isolated
diff ALmixer.c @ 13:54aa96ae8912
Added LinkedList class to project.
ALmixer now saves ALmixer_Data instances in a private linked list so when Quit is called, this memory can be cleaned up.
This is meant to deal with two problems. First, SDL_sound does something similar which means since I wrap SDL_sound structures, I may be left with dangling pointers if. Second is the obvious auto-cleanup when quiting which is convenient for resetting.
author | Eric Wing <ewing . public |-at-| gmail . com> |
---|---|
date | Sat, 06 Nov 2010 00:37:29 -0700 |
parents | bfe90b4f3d87 |
children | 038baa026db3 |
line wrap: on
line diff
--- a/ALmixer.c Fri Nov 05 20:59:13 2010 -0700 +++ b/ALmixer.c Sat Nov 06 00:37:29 2010 -0700 @@ -62,6 +62,12 @@ */ #include "CircularQueue.h" +/* SDL_sound keeps a private linked list of sounds which get auto-deleted + * on Sound_Quit. This might actually create some leaks for me in certain + * usage patterns. To be safe, I should do the same. + */ +#include "LinkedList.h" + #ifdef ENABLE_ALMIXER_THREADS /* Needed for the Mutex locks (and threads if enabled) */ #ifdef ALMIXER_COMPILE_WITHOUT_SDL @@ -227,6 +233,9 @@ static SDL_Thread* Stream_Thread_global = NULL; #endif +static LinkedList* s_listOfALmixerData = NULL; + + #ifdef __APPLE__ static ALvoid Internal_alcMacOSXMixerOutputRate(const ALdouble sample_rate) @@ -6398,11 +6407,24 @@ Channel_Data_Callback = NULL; Channel_Data_Callback_Userdata = NULL; + /* Allocate memory for linked list of ALmixerData. */ + s_listOfALmixerData = LinkedList_Create(); + if(NULL == s_listOfALmixerData) + { + ALmixer_SetError("Couldn't create linked list"); + alcDestroyContext(context); + alcCloseDevice(dev); + ALmixer_Initialized = 0; + Number_of_Channels_global = 0; + return AL_FALSE; + } + /* Allocate memory for the list of channels */ ALmixer_Channel_List = (struct ALmixer_Channel*) malloc(Number_of_Channels_global * sizeof(struct ALmixer_Channel)); if(NULL == ALmixer_Channel_List) { ALmixer_SetError("Out of Memory for Channel List"); + LinkedList_Free(s_listOfALmixerData); alcDestroyContext(context); alcCloseDevice(dev); ALmixer_Initialized = 0; @@ -6416,6 +6438,7 @@ { ALmixer_SetError("Out of Memory for Source Map List"); free(ALmixer_Channel_List); + LinkedList_Free(s_listOfALmixerData); alcDestroyContext(context); alcCloseDevice(dev); ALmixer_Initialized = 0; @@ -6430,6 +6453,7 @@ ALmixer_SetError("Out of Memory for sources"); free(Source_Map_List); free(ALmixer_Channel_List); + LinkedList_Free(s_listOfALmixerData); alcDestroyContext(context); alcCloseDevice(dev); ALmixer_Initialized = 0; @@ -6446,6 +6470,7 @@ ALmixer_SetError("Couldn't generate sources: %s\n", alGetString(error)); free(ALmixer_Channel_List); free(Source_Map_List); + LinkedList_Free(s_listOfALmixerData); alcDestroyContext(context); alcCloseDevice(dev); ALmixer_Initialized = 0; @@ -6486,6 +6511,9 @@ /* ALmixer_OutputDecoders(); */ + + + #ifdef ENABLE_ALMIXER_THREADS s_simpleLock = SDL_CreateMutex(); if(NULL == s_simpleLock) @@ -6494,6 +6522,7 @@ free(source); free(ALmixer_Channel_List); free(Source_Map_List); + LinkedList_Free(s_listOfALmixerData); alcDestroyContext(context); alcCloseDevice(dev); ALmixer_Initialized = 0; @@ -6510,6 +6539,7 @@ free(source); free(ALmixer_Channel_List); free(Source_Map_List); + LinkedList_Free(s_listOfALmixerData); alcDestroyContext(context); alcCloseDevice(dev); ALmixer_Initialized = 0; @@ -6948,11 +6978,23 @@ Channel_Data_Callback = NULL; Channel_Data_Callback_Userdata = NULL; + /* Allocate memory for linked list of ALmixerData. */ + s_listOfALmixerData = LinkedList_Create(); + if(NULL == s_listOfALmixerData) + { + ALmixer_SetError("Couldn't create linked list"); + ALmixer_Initialized = 0; + Number_of_Channels_global = 0; + return AL_FALSE; + } + + /* Allocate memory for the list of channels */ ALmixer_Channel_List = (struct ALmixer_Channel*) malloc(Number_of_Channels_global * sizeof(struct ALmixer_Channel)); if(NULL == ALmixer_Channel_List) { ALmixer_SetError("Out of Memory for Channel List"); + LinkedList_Free(s_listOfALmixerData); ALmixer_Initialized = 0; Number_of_Channels_global = 0; return AL_FALSE; @@ -6964,6 +7006,7 @@ { ALmixer_SetError("Out of Memory for Source Map List"); free(ALmixer_Channel_List); + LinkedList_Free(s_listOfALmixerData); ALmixer_Initialized = 0; Number_of_Channels_global = 0; return AL_FALSE; @@ -6976,6 +7019,7 @@ ALmixer_SetError("Out of Memory for sources"); free(Source_Map_List); free(ALmixer_Channel_List); + LinkedList_Free(s_listOfALmixerData); ALmixer_Initialized = 0; Number_of_Channels_global = 0; return AL_FALSE; @@ -6990,6 +7034,7 @@ ALmixer_SetError("Couldn't generate sources: %s\n", alGetString(error)); free(ALmixer_Channel_List); free(Source_Map_List); + LinkedList_Free(s_listOfALmixerData); ALmixer_Initialized = 0; Number_of_Channels_global = 0; return AL_FALSE; @@ -7121,6 +7166,17 @@ } alcCloseDevice(dev); + /* Delete the list of ALmixerData's before Sound_Quit deletes + * its own underlying information and I potentially have dangling pointers. + */ + while(LinkedList_Size(s_listOfALmixerData) > 0) + { + ALmixer_Data* almixer_data = LinkedList_PopBack(s_listOfALmixerData); + ALmixer_FreeData(almixer_data); + } + LinkedList_Free(s_listOfALmixerData); + s_listOfALmixerData = NULL; + Sound_Quit(); #ifdef ALMIXER_COMPILE_WITHOUT_SDL @@ -7857,6 +7913,10 @@ return NULL; } + /* Add the ALmixerData to an internal linked list so we can delete it on + * quit and avoid messy dangling issues with Sound_Quit + */ + LinkedList_PushBack(s_listOfALmixerData, ret_data); return ret_data; } @@ -8139,6 +8199,11 @@ } } free(data->buffer); + + LinkedList_Remove(s_listOfALmixerData, + LinkedList_Find(s_listOfALmixerData, data, NULL) + ); + free(data); }