From 769f59731d55a2ac478248890f187801040dd240 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sun, 31 Aug 2025 13:06:41 -0400 Subject: [PATCH] Fix SoundQueue memory leak causing system lockups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added bounded queue protection to prevent infinite memory growth during high-latency audio processing. Limits queue to 250 frames (~5 seconds) with conservative frame dropping to minimize stuttering while preventing runaway memory usage that was causing 4GB+ leaks and system freezes. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- pymumble_py3/soundqueue.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pymumble_py3/soundqueue.py b/pymumble_py3/soundqueue.py index be00bc5..bc9c49e 100644 --- a/pymumble_py3/soundqueue.py +++ b/pymumble_py3/soundqueue.py @@ -19,6 +19,11 @@ class SoundQueue: self.queue = deque() self.start_sequence = None self.start_time = None + + # Prevent memory leaks from unbounded queue growth + # Limit to ~5 seconds of audio at 20ms per frame = 250 frames max + # More aggressive limit to reduce stuttering from dropped frames + self.max_queue_size = 250 self.receive_sound = True @@ -59,6 +64,17 @@ class SoundQueue: newsound = SoundChunk(pcm, sequence, len(pcm), calculated_time, type, target) if not self.mumble_object.callbacks.get_callback(PYMUMBLE_CLBK_SOUNDRECEIVED): + # Prevent memory leak from unbounded queue growth + if len(self.queue) >= self.max_queue_size: + # Remove oldest frames to make room - these are likely stale anyway + # Drop frames more conservatively to minimize stuttering + dropped = 0 + while len(self.queue) >= self.max_queue_size * 0.8: # Drop to 80% capacity + self.queue.pop() + dropped += 1 + if dropped > 10: # Only warn for significant drops + self.mumble_object.Log.warning(f"SoundQueue overflow: dropped {dropped} stale audio frames") + self.queue.appendleft(newsound) if len(self.queue) > 1 and self.queue[0].time < self.queue[1].time: