Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:favogt:boo1201349
pipewire
0001-spa-alsa-udev-Check-accessibility-of-pcm-d...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-spa-alsa-udev-Check-accessibility-of-pcm-devices-as-.patch of Package pipewire
From 0eb7f097129e35fba4aeeba518a2bc79d96fed44 Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fvogt@suse.de> Date: Wed, 13 Jul 2022 10:47:22 +0200 Subject: [PATCH] spa/alsa-udev: Check accessibility of pcm devices as well The order of attribute changes is random, so it's possible that controlCX is accessible before the other devices, which marks the device as available but it actually fails to open. Only consider the device accessible if both control and PCM devices can be accessed. This requires reacting to ATTRIB changes of pcm devices as well now. Fixes #2534 --- spa/plugins/alsa/alsa-udev.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/spa/plugins/alsa/alsa-udev.c b/spa/plugins/alsa/alsa-udev.c index aa7b03994..8ee217d9d 100644 --- a/spa/plugins/alsa/alsa-udev.c +++ b/spa/plugins/alsa/alsa-udev.c @@ -538,11 +538,35 @@ static int emit_object_info(struct impl *this, struct device *device) static bool check_access(struct impl *this, struct device *device) { - char path[128]; - bool accessible; + char path[128], prefix[32]; + DIR *snd = NULL; + struct dirent *entry; + bool accessible = false; snprintf(path, sizeof(path), "/dev/snd/controlC%u", device->id); - accessible = access(path, R_OK|W_OK) >= 0; + if (access(path, R_OK|W_OK) >= 0 && (snd = opendir("/dev/snd"))) { + /* + * It's possible that controlCX is accessible before pcmCX* or + * the other way around. Return true only if all devices are + * accessible. + */ + + accessible = true; + spa_scnprintf(prefix, sizeof(prefix), "pcmC%uD", device->id); + while ((entry = readdir(snd)) != NULL) { + if (!(entry->d_type == DT_CHR && + spa_strstartswith(entry->d_name, prefix))) + continue; + + snprintf(path, sizeof(path), "/dev/snd/%.32s", entry->d_name); + if (access(path, R_OK|W_OK) < 0) { + accessible = false; + break; + } + } + closedir(snd); + } + if (accessible != device->accessible) spa_log_debug(this->log, "%s accessible:%u", path, accessible); device->accessible = accessible; @@ -655,10 +679,6 @@ static void impl_on_notify_events(struct spa_source *source) /* Device becomes accessible or not busy */ if ((event->mask & (IN_ATTRIB | IN_CLOSE_WRITE))) { bool access; - - if ((event->mask & IN_ATTRIB) && - spa_strstartswith(event->name, "pcm")) - continue; if (sscanf(event->name, "controlC%u", &id) != 1 && sscanf(event->name, "pcmC%uD", &id) != 1) continue; -- 2.36.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor