fix(pulseaudio): release server-side stream on Stream::drop#1189
Open
knz wants to merge 1 commit intoRustAudio:masterfrom
Open
fix(pulseaudio): release server-side stream on Stream::drop#1189knz wants to merge 1 commit intoRustAudio:masterfrom
knz wants to merge 1 commit intoRustAudio:masterfrom
Conversation
The PulseAudio backend spawns a driver thread that calls `pulseaudio::PlaybackStream::play_all`, which awaits source EOF before draining and exiting. EOF for a `PlaybackSource` is signalled by `poll_read` returning `0`, but the data-callback wrapper used by `new_playback` always reports the full buffer length to satisfy cpal's no-short-write contract. The driver thread therefore parks in `source_eof` for the lifetime of the process. Because that thread holds a `PlaybackStream` clone (an `Arc<InnerPlaybackStream>`), the inner Arc count never drops to zero, `InnerPlaybackStream::drop` never fires, and the `DeletePlaybackStream` command it would otherwise queue is never sent. Each `Stream` created and dropped by the user thus leaks one server-side stream and one OS thread; long-running clients accumulate `pactl list short sink-inputs` entries until PulseAudio runs out of channels. Queue a `DeletePlaybackStream` from `Stream::drop` so the reactor removes the stream state, drops the source's `eof_tx` channel, and wakes the driver thread with a cancellation error. `now_or_never` mirrors `InnerPlaybackStream::drop` and avoids blocking in `Drop`. Fixes RustAudio#1188.
Author
|
NB: cleanup is asynchronous (the delete is queued, not awaited), so a |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The PulseAudio backend spawns a driver thread that calls
pulseaudio::PlaybackStream::play_all, which awaits source EOF before draining and exiting. EOF for aPlaybackSourceis signalled bypoll_readreturning0, but the data-callback wrapper used bynew_playbackalways reports the full buffer length to satisfy cpal's no-short-write contract. The driver thread therefore parks insource_eoffor the lifetime of the process.Because that thread holds a
PlaybackStreamclone (anArc<InnerPlaybackStream>), the inner Arc count never drops to zero,InnerPlaybackStream::dropnever fires, and theDeletePlaybackStreamcommand it would otherwise queue is never sent. EachStreamcreated and dropped by the user thus leaks one server-side stream and one OS thread; long-running clients accumulatepactl list short sink-inputsentries until PulseAudio runs out of channels.Queue a
DeletePlaybackStreamfromStream::dropso the reactor removes the stream state, drops the source'seof_txchannel, and wakes the driver thread with a cancellation error.now_or_nevermirrorsInnerPlaybackStream::dropand avoids blocking inDrop.Fixes #1188.