summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan C. Gordon <icculus@icculus.org>2016-08-06 02:27:55 -0400
committerRyan C. Gordon <icculus@icculus.org>2016-08-06 02:27:55 -0400
commit913665ffd809014fb99b0b2f29b72cd80c1c17db (patch)
tree6e52e70746990b4b8ce964a90cab76cf93f83f5c
parent1684861ef8632123a2862cbe05d7bd092057caf2 (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.c30
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);
}