diff options
author | Ryan C. Gordon <icculus@icculus.org> | 2016-08-06 02:27:55 -0400 |
---|---|---|
committer | Ryan C. Gordon <icculus@icculus.org> | 2016-08-06 02:27:55 -0400 |
commit | 913665ffd809014fb99b0b2f29b72cd80c1c17db (patch) | |
tree | 6e52e70746990b4b8ce964a90cab76cf93f83f5c | |
parent | 1684861ef8632123a2862cbe05d7bd092057caf2 (diff) |
audio: SDL_ClearQueuedAudio() should free everything but two packets.
Otherwise, if you had a massive, one-time queue buildup, the memory from that
remains allocated until you close the device. Also, if you are just using a
reasonable amount of space, this would previously cause you to reallocate it
over and over instead of keeping a little bit of memory around.
-rw-r--r-- | src/audio/SDL_audio.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 4c43693427..ec3817bb48 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -586,20 +586,44 @@ void SDL_ClearQueuedAudio(SDL_AudioDeviceID devid) { SDL_AudioDevice *device = get_audio_device(devid); - SDL_AudioBufferQueue *buffer = NULL; + SDL_AudioBufferQueue *packet; + if (!device) { return; /* nothing to do. */ } /* Blank out the device and release the mutex. Free it afterwards. */ current_audio.impl.LockDevice(device); - buffer = device->buffer_queue_head; + + /* merge the available pool and the current queue into one list. */ + packet = device->buffer_queue_head; + if (packet) { + device->buffer_queue_tail->next = device->buffer_queue_pool; + } else { + packet = device->buffer_queue_pool; + } + + /* Remove the queued packets from the device. */ device->buffer_queue_tail = NULL; device->buffer_queue_head = NULL; device->queued_bytes = 0; + device->buffer_queue_pool = packet; + + /* Keep up to two packets in the pool to reduce future malloc pressure. */ + if (packet) { + if (!packet->next) { + packet = NULL; /* one packet (the only one) for the pool. */ + } else { + SDL_AudioBufferQueue *next = packet->next->next; + packet->next->next = NULL; /* two packets for the pool. */ + packet = next; /* rest will be freed. */ + } + } + current_audio.impl.UnlockDevice(device); - free_audio_queue(buffer); + /* free any extra packets we didn't keep in the pool. */ + free_audio_queue(packet); } |