Bug 103498 - Closing PulseAudio freezes SDL audio
Summary: Closing PulseAudio freezes SDL audio
Status: RESOLVED MOVED
Alias: None
Product: PulseAudio
Classification: Unclassified
Component: core (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: pulseaudio-bugs
QA Contact: pulseaudio-bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-28 19:03 UTC by Jussi Pakkanen
Modified: 2018-07-30 10:05 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments

Description Jussi Pakkanen 2017-10-28 19:03:59 UTC
This is a slightly weird bug. When using SDL mixer (1.2) to play music on 32 bit x86 Linux boxes, things works perfectly most of the time. However every now and then things break down when closing down the SDL audio device.

The actual freeze happens inside PulseAudio. SDL's deinit calls into PA, which does a pthread_join that never returns. When this happens if there is an another SDL sound player it keeps on working perfectly. Trying to open a new SDL audio player fails. Restarting PA fixes the issue so new music players can be opened, but it does not work reliably.

Detected with PA 5 but replicated as well with PA 10.
Comment 1 Tanu Kaskinen 2017-11-02 10:31:19 UTC
Can you provide a backtrace for all threads in the SDL audio player? Apparently one thread calls pa_threaded_mainloop_stop(), and that will wait for the thread where the libpulse mainloop is running to quit. I don't think the mainloop thread should block on anything, but maybe there's some application callback doing something that it shouldn't do.

Is this audio player available somewhere in case I want to try to reproduce?
Comment 2 Jussi Pakkanen 2017-11-06 18:44:09 UTC
Unfortunately the player is closed source. However I managed to reduce it to the following piece of code:

void* check_audio_freeze(void *_) {
  if(SDL_Init(SDL_INIT_AUDIO) < 0) {
    printf("SDL_Init: %s\n", SDL_GetError());
    return NULL;
  }
  int flags = MIX_INIT_OGG;
  int initted = Mix_Init(flags);

  if((initted&flags) != flags) {
    goto sdl_deinit;
  }

  if(Mix_OpenAudio(44100, AUDIO_S16, 2, 512) < 0) {
    printf("Mix_OpenAudio: %s\n", Mix_GetError());
    goto mix_deinit;
  }

  Mix_AllocateChannels(64);

  Mix_CloseAudio();
 mix_deinit:
  Mix_Quit();
 sdl_deinit:
  SDL_Quit();
  return NULL;
}

Once Pulseaudio has frozen, even new executables (such as the one above) will freeze when trying to deinitialize the sound system.

I also forgot to mention that this is a semi-embedded Linux distribution that runs PA in system mode. I have tried to reproduce this issue on a stock distro but thus far has been unsuccessfull (but the bug happens very rarely even on the custom distro).
Comment 3 Tanu Kaskinen 2017-11-08 12:45:42 UTC
So it's really the pulseaudio daemon that is freezing? You said in the initial report that the freeze happens inside pulseaudio, but "SDL's deinit calls into PA, which does a pthread_join that never returns" made me think that by pulseaudio you're probably referring to libpulse in the application process.

Can you get a backtrace from the frozen daemon?

I'll try reproducing, but based on your reproducibility comment that will probably be futile.
Comment 4 Tanu Kaskinen 2017-11-09 12:23:41 UTC
1000 runs of the code didn't cause any freezing.
Comment 5 Jussi Pakkanen 2017-11-26 20:22:41 UTC
This bug is nasty because it most likely boils down to a race condition that happens very rarely. This is what we came up with:

- machine is booted
- pulseaudio starts up in system mode
- in some circumstances PA's startup is delayed, and the program using SDL audio starts up and grabs the sound card before PA is fully running
- PA is now running, and the first application is using SDL audio, but it is using Alsa directly
- programs started after PA starts try to connect to PA, succeed, and send their sound data there but PA can't play it because the sound card is held by the first launched application
- when closing one of the applications that are started afterwards, they get hung in the method described above

We tried delaying the startup with systemd rules so that the application is only started after PA's control socket appears. This did not work. The only thing that did work was creating a startup application that tries to open SDL audio, forcing it to use PA and delay starting any other program until it has successfully opened a PA audio connection.
Comment 6 GitLab Migration User 2018-07-30 10:05:22 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/203.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.