mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
alsa: update pollfd from poll_revents() as well
Some clients don't call _poll_descriptors() before entering the poll and so don't get updated fds. This would result in a whole bunch of wakeups when the eventfd was set but the new state is no longer active. Part of the problem is also that check_active() returns the desired new state and update_active() does check_active() + update. We could be getting into a new desired inactive state without updating the eventfd. Improve this by merging them together into update_active() which only writes/reads the eventfd when something changes. This also makes things less heavy because the eventfd is only read/written when needed. Fixes #3648
This commit is contained in:
parent
0278695e7d
commit
266ef3b986
1 changed files with 20 additions and 21 deletions
|
|
@ -89,7 +89,7 @@ typedef struct {
|
||||||
|
|
||||||
static int snd_pcm_pipewire_stop(snd_pcm_ioplug_t *io);
|
static int snd_pcm_pipewire_stop(snd_pcm_ioplug_t *io);
|
||||||
|
|
||||||
static int check_active(snd_pcm_ioplug_t *io)
|
static int update_active(snd_pcm_ioplug_t *io)
|
||||||
{
|
{
|
||||||
snd_pcm_pipewire_t *pw = io->private_data;
|
snd_pcm_pipewire_t *pw = io->private_data;
|
||||||
snd_pcm_sframes_t avail;
|
snd_pcm_sframes_t avail;
|
||||||
|
|
@ -97,7 +97,10 @@ static int check_active(snd_pcm_ioplug_t *io)
|
||||||
|
|
||||||
avail = snd_pcm_ioplug_avail(io, pw->hw_ptr, io->appl_ptr);
|
avail = snd_pcm_ioplug_avail(io, pw->hw_ptr, io->appl_ptr);
|
||||||
|
|
||||||
if (io->state == SND_PCM_STATE_DRAINING) {
|
if (pw->error > 0) {
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
else if (io->state == SND_PCM_STATE_DRAINING) {
|
||||||
active = pw->drained;
|
active = pw->drained;
|
||||||
}
|
}
|
||||||
else if (avail >= 0 && avail < (snd_pcm_sframes_t)pw->min_avail) {
|
else if (avail >= 0 && avail < (snd_pcm_sframes_t)pw->min_avail) {
|
||||||
|
|
@ -105,33 +108,27 @@ static int check_active(snd_pcm_ioplug_t *io)
|
||||||
}
|
}
|
||||||
else if (avail >= (snd_pcm_sframes_t)pw->min_avail) {
|
else if (avail >= (snd_pcm_sframes_t)pw->min_avail) {
|
||||||
active = true;
|
active = true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
active = false;
|
active = false;
|
||||||
}
|
}
|
||||||
if (pw->active != active) {
|
if (pw->active != active) {
|
||||||
|
uint64_t val;
|
||||||
|
|
||||||
pw_log_trace("%p: avail:%lu min-avail:%lu state:%s hw:%lu appl:%lu active:%d->%d state:%s",
|
pw_log_trace("%p: avail:%lu min-avail:%lu state:%s hw:%lu appl:%lu active:%d->%d state:%s",
|
||||||
pw, avail, pw->min_avail, snd_pcm_state_name(io->state),
|
pw, avail, pw->min_avail, snd_pcm_state_name(io->state),
|
||||||
pw->hw_ptr, io->appl_ptr, pw->active, active,
|
pw->hw_ptr, io->appl_ptr, pw->active, active,
|
||||||
snd_pcm_state_name(io->state));
|
snd_pcm_state_name(io->state));
|
||||||
|
|
||||||
|
pw->active = active;
|
||||||
|
if (active)
|
||||||
|
spa_system_eventfd_write(pw->system, io->poll_fd, 1);
|
||||||
|
else
|
||||||
|
spa_system_eventfd_read(pw->system, io->poll_fd, &val);
|
||||||
}
|
}
|
||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int update_active(snd_pcm_ioplug_t *io)
|
|
||||||
{
|
|
||||||
snd_pcm_pipewire_t *pw = io->private_data;
|
|
||||||
pw->active = check_active(io);
|
|
||||||
uint64_t val;
|
|
||||||
|
|
||||||
if (pw->active || pw->error < 0)
|
|
||||||
spa_system_eventfd_write(pw->system, io->poll_fd, 1);
|
|
||||||
else
|
|
||||||
spa_system_eventfd_read(pw->system, io->poll_fd, &val);
|
|
||||||
|
|
||||||
return pw->active;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw)
|
static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw)
|
||||||
{
|
{
|
||||||
if (pw == NULL)
|
if (pw == NULL)
|
||||||
|
|
@ -182,11 +179,13 @@ static int snd_pcm_pipewire_poll_revents(snd_pcm_ioplug_t *io,
|
||||||
if (pw->error < 0)
|
if (pw->error < 0)
|
||||||
return pw->error;
|
return pw->error;
|
||||||
|
|
||||||
|
update_active(io);
|
||||||
|
|
||||||
*revents = pfds[0].revents & ~(POLLIN | POLLOUT);
|
*revents = pfds[0].revents & ~(POLLIN | POLLOUT);
|
||||||
if (pfds[0].revents & POLLIN && check_active(io)) {
|
if (pfds[0].revents & POLLIN && pw->active)
|
||||||
*revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN;
|
*revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN;
|
||||||
update_active(io);
|
|
||||||
}
|
pw_log_trace_fp("poll %d", *revents);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue