renpy / pygame_sdl2

Reimplementation of portions of the pygame API using SDL2.
GNU Lesser General Public License v2.1
326 stars 64 forks source link

pygame_sdl2.mixer: channel_callback sometimes causes the app to hang indefinitely #58

Closed peacegiverman closed 7 years ago

peacegiverman commented 8 years ago

This is more likely to happen when there are a lot of sounds being played and stopped. pygame_sdl2.mixer.channel_callback will sometimes get stuck waiting for GIL indefinitely, causing the app to hang.

The solution is to make calls to SDL Mixer functions such as Mix_PlayChannelTimed, Mix_HaltChannel and Mix_FadeOutChannel in no GIL mode.

I think this problem is caused by a race condition. AFAIK, SDL uses a separate thread for audio. When we call Mix_HaltChannel for example, it probably switches to another thread, where it stops the audio playing and then executes the callback. Sometimes the call returns before the audio thread requests the callback and everything works fine, and sometimes, the callback gets called before Mix_HaltChannel returns and releases the GIL, leading to a deadlock. That's why calling these methods in nogil fixes the issue.

I'll submit a pull request with the fix soon.

renpytom commented 8 years ago

Makes sense. I'll merge the fix once I see it.