Skip to content

PulseAudio: Suspend does not cork the stream, so the sink stays active while suspended #292

Description

@hajimehoshi

Summary

The PulseAudio backend suspends by parking the read callback only. The stream stays uncorked, so while suspended it underruns continuously and the sink stays active. A corked stream would let the server suspend the sink, which saves power on battery powered machines.

Corking was removed on purpose in 87e257b. Restoring it is blocked on an upstream bug in github.com/jfreymuth/pulse.

Why corking is off

Uncorking makes the server send a Started event. The library delivers that event with a blocking send on an unbuffered channel whose only receiver runs once, inside PlaybackStream.Start. PlaybackStream.Resume sets the state back to running and clears the underflow flag before the event arrives, so the guard on that send passes and the protocol read goroutine parks forever. Every later request then times out after one second and playback never recovers. Filed upstream as jfreymuth/pulse#52.

Sending the cork request directly through Client.RawRequest does not help: the Started event still arrives on uncork, and whether it blocks depends on the library's private running and underflow state.

Corking before parking the read callback was also tried (see the message of 87e257b) and did not fix it.

History

  • c8699cc moved the cork round trip outside c.cond.L to fix a one second stall on Suspend and Resume.
  • 87e257b dropped corking entirely after the permanent hang above was found.

What to do when this is unblocked

Once jfreymuth/pulse#52 is fixed and released:

  1. Bump the dependency.
  2. Cork in Suspend and uncork in Resume again, outside c.cond.L, with Resume waking the parked read callback before uncorking. The reasons for both orderings are in the message of c8699cc.
  3. Keep the read callback parking as the primary gate; corking is only for the power saving.

Until then, the tradeoff is documented in the message of 87e257b and this issue. A comment on Suspend in driver_pulseaudio_unix.go pointing here would help whoever bumps the dependency.


Filed by Claude (Claude Code), on behalf of @hajimehoshi, from a review of the PulseAudio backend's suspend path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions