Mercurial > almixer_isolated
changeset 37:b346b6608eab
Fixed memory leak in Quit due to changes related to background thread removal. FreeData was quick escaping because it checked for ALmixer_Initialized which is now false by the time the code is reached.
Code was refactored to introduce an Internal_FreeData which skips this check.
Also, I think there is another 'bug' where I should actually be able to delete buffers even though the context is NULL as long as there is a device. But this is all really ugly corner case stuff.
author | Eric Wing <ewing@anscamobile.com> |
---|---|
date | Mon, 11 Apr 2011 17:19:24 -0700 |
parents | b65ad8b6ccf3 |
children | 71b465ff0622 e10dd3056782 |
files | ALmixer.c |
diffstat | 1 files changed, 63 insertions(+), 56 deletions(-) [+] |
line wrap: on
line diff
--- a/ALmixer.c Thu Apr 07 19:19:07 2011 -0700 +++ b/ALmixer.c Mon Apr 11 17:19:24 2011 -0700 @@ -4773,6 +4773,65 @@ +static void Internal_FreeData(ALmixer_Data* data) +{ + ALenum error; + if(NULL == data) + { + return; + } + + if(data->decoded_all) + { + /* If access_data was enabled, then the Sound_Sample* + * still exists. We need to free it + */ + if(data->sample != NULL) + { + Sound_FreeSample(data->sample); + } + alDeleteBuffers(1, data->buffer); + if((error = alGetError()) != AL_NO_ERROR) + { + fprintf(stderr, "ALmixer_FreeData: alDeleteBuffers failed. %s\n", alGetString(error)); + } + } + else + { + ALuint i; + + /* Delete buffer copies if access_data was enabled */ + if(data->buffer_map_list != NULL) + { + for(i=0; i<data->max_queue_buffers; i++) + { + free(data->buffer_map_list[i].data); + } + free(data->buffer_map_list); + } + if(data->circular_buffer_queue != NULL) + { + CircularQueueUnsignedInt_FreeQueue(data->circular_buffer_queue); + } + + Sound_FreeSample(data->sample); + alDeleteBuffers(data->max_queue_buffers, data->buffer); + if((error = alGetError()) != AL_NO_ERROR) + { + fprintf(stderr, "ALmixer_FreeData: alDeleteBuffers failed. %s\n", alGetString(error)); + } + } + free(data->buffer); + + LinkedList_Remove(s_listOfALmixerData, + LinkedList_Find(s_listOfALmixerData, data, NULL) + ); + + free(data); +} + + + @@ -7517,7 +7576,8 @@ { /* Note that ALmixer_FreeData will remove the data from the linked list for us so don't pop the list here. */ ALmixer_Data* almixer_data = LinkedList_PopBack(s_listOfALmixerData); - ALmixer_FreeData(almixer_data); + /* Watch out: ALmixer_FreeData used to escape because ALmixer_Initialized is now false. */ + Internal_FreeData(almixer_data); } LinkedList_Free(s_listOfALmixerData); s_listOfALmixerData = NULL; @@ -8540,75 +8600,22 @@ } - - void ALmixer_FreeData(ALmixer_Data* data) { - ALenum error; - if(NULL == data) - { - return; - } - if(AL_FALSE == ALmixer_Initialized) { return; } /* Bypass if in interruption event */ + /* FIXME: Buffers are connected to devices, sources are connected to contexts. I should still be able to delete the buffers even if there is no context. */ if(NULL == alcGetCurrentContext()) { fprintf(stderr, "ALmixer_FreeData: Programmer Error. You cannot delete data when the OpenAL content is currently NULL. You may have already called ALmixer_Quit() or are in an interruption event\n"); return; } - if(data->decoded_all) - { - /* If access_data was enabled, then the Sound_Sample* - * still exists. We need to free it - */ - if(data->sample != NULL) - { - Sound_FreeSample(data->sample); - } - alDeleteBuffers(1, data->buffer); - if((error = alGetError()) != AL_NO_ERROR) - { - fprintf(stderr, "ALmixer_FreeData: alDeleteBuffers failed. %s\n", alGetString(error)); - } - } - else - { - ALuint i; - - /* Delete buffer copies if access_data was enabled */ - if(data->buffer_map_list != NULL) - { - for(i=0; i<data->max_queue_buffers; i++) - { - free(data->buffer_map_list[i].data); - } - free(data->buffer_map_list); - } - if(data->circular_buffer_queue != NULL) - { - CircularQueueUnsignedInt_FreeQueue(data->circular_buffer_queue); - } - - Sound_FreeSample(data->sample); - alDeleteBuffers(data->max_queue_buffers, data->buffer); - if((error = alGetError()) != AL_NO_ERROR) - { - fprintf(stderr, "ALmixer_FreeData: alDeleteBuffers failed. %s\n", alGetString(error)); - } - } - free(data->buffer); - - LinkedList_Remove(s_listOfALmixerData, - LinkedList_Find(s_listOfALmixerData, data, NULL) - ); - - free(data); + Internal_FreeData(data); } ALint ALmixer_GetTotalTime(ALmixer_Data* data)