mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
spa: alsa,v4l2: avoid double access check on inotify events
Previously both `impl_on_notify_events()` and `process_{device,card}()`
called `check_access()`. Avoid that by merging `ACTION_ADD` and
`ACTION_DISABLE` into a single `ACTION_CHANGE` and let `process_{device,card}()`
call `check_access()` and decide what to do.
This commit is contained in:
parent
0158b5dcb6
commit
ad975c93ee
2 changed files with 47 additions and 69 deletions
|
|
@ -32,9 +32,8 @@
|
||||||
#define MAX_CARDS 64
|
#define MAX_CARDS 64
|
||||||
|
|
||||||
enum action {
|
enum action {
|
||||||
ACTION_ADD,
|
ACTION_CHANGE,
|
||||||
ACTION_REMOVE,
|
ACTION_REMOVE,
|
||||||
ACTION_DISABLE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used for unavailable devices in the card structure. */
|
/* Used for unavailable devices in the card structure. */
|
||||||
|
|
@ -723,26 +722,34 @@ static void process_card(struct impl *this, enum action action, struct card *car
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ACTION_ADD: {
|
case ACTION_CHANGE: {
|
||||||
if (!check_access(this, card))
|
check_access(this, card);
|
||||||
return;
|
if (card->accessible && !card->emitted) {
|
||||||
int res = emit_added_object_info(this, card);
|
int res = emit_added_object_info(this, card);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
if (card->ignored)
|
if (card->ignored)
|
||||||
spa_log_info(this->log, "ALSA card %u unavailable (%s): it is ignored",
|
spa_log_info(this->log, "ALSA card %u unavailable (%s): it is ignored",
|
||||||
card->card_nr, spa_strerror(res));
|
card->card_nr, spa_strerror(res));
|
||||||
else if (!card->unavailable)
|
else if (!card->unavailable)
|
||||||
spa_log_info(this->log, "ALSA card %u unavailable (%s): wait for it",
|
spa_log_info(this->log, "ALSA card %u unavailable (%s): wait for it",
|
||||||
card->card_nr, spa_strerror(res));
|
card->card_nr, spa_strerror(res));
|
||||||
else
|
else
|
||||||
spa_log_debug(this->log, "ALSA card %u still unavailable (%s)",
|
spa_log_debug(this->log, "ALSA card %u still unavailable (%s)",
|
||||||
card->card_nr, spa_strerror(res));
|
card->card_nr, spa_strerror(res));
|
||||||
card->unavailable = true;
|
card->unavailable = true;
|
||||||
} else {
|
} else {
|
||||||
if (card->unavailable)
|
if (card->unavailable)
|
||||||
spa_log_info(this->log, "ALSA card %u now available",
|
spa_log_info(this->log, "ALSA card %u now available",
|
||||||
card->card_nr);
|
card->card_nr);
|
||||||
card->unavailable = false;
|
card->unavailable = false;
|
||||||
|
}
|
||||||
|
} else if (!card->accessible && card->emitted) {
|
||||||
|
card->emitted = false;
|
||||||
|
|
||||||
|
if (card->pcm_device_id != ID_DEVICE_NOT_SUPPORTED)
|
||||||
|
spa_device_emit_object_info(&this->hooks, card->pcm_device_id, NULL);
|
||||||
|
if (card->compress_offload_device_id != ID_DEVICE_NOT_SUPPORTED)
|
||||||
|
spa_device_emit_object_info(&this->hooks, card->compress_offload_device_id, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -761,22 +768,6 @@ static void process_card(struct impl *this, enum action action, struct card *car
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ACTION_DISABLE:
|
|
||||||
if (card->emitted) {
|
|
||||||
uint32_t pcm_device_id, compress_offload_device_id;
|
|
||||||
|
|
||||||
pcm_device_id = card->pcm_device_id;
|
|
||||||
compress_offload_device_id = card->compress_offload_device_id;
|
|
||||||
|
|
||||||
card->emitted = false;
|
|
||||||
|
|
||||||
if (pcm_device_id != ID_DEVICE_NOT_SUPPORTED)
|
|
||||||
spa_device_emit_object_info(&this->hooks, pcm_device_id, NULL);
|
|
||||||
if (compress_offload_device_id != ID_DEVICE_NOT_SUPPORTED)
|
|
||||||
spa_device_emit_object_info(&this->hooks, compress_offload_device_id, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -789,7 +780,7 @@ static void process_udev_device(struct impl *this, enum action action, struct ud
|
||||||
return;
|
return;
|
||||||
|
|
||||||
card = find_card(this, card_nr);
|
card = find_card(this, card_nr);
|
||||||
if (action == ACTION_ADD && !card)
|
if (action == ACTION_CHANGE && !card)
|
||||||
card = add_card(this, card_nr, udev_device);
|
card = add_card(this, card_nr, udev_device);
|
||||||
|
|
||||||
if (!card)
|
if (!card)
|
||||||
|
|
@ -841,18 +832,13 @@ static void impl_on_notify_events(struct spa_source *source)
|
||||||
|
|
||||||
/* card becomes accessible or not busy */
|
/* card becomes accessible or not busy */
|
||||||
if ((event->mask & (IN_ATTRIB | IN_CLOSE_WRITE))) {
|
if ((event->mask & (IN_ATTRIB | IN_CLOSE_WRITE))) {
|
||||||
bool access;
|
|
||||||
if (sscanf(event->name, "controlC%u", &card_nr) != 1 &&
|
if (sscanf(event->name, "controlC%u", &card_nr) != 1 &&
|
||||||
sscanf(event->name, "pcmC%uD", &card_nr) != 1)
|
sscanf(event->name, "pcmC%uD", &card_nr) != 1)
|
||||||
continue;
|
continue;
|
||||||
if ((card = find_card(this, card_nr)) == NULL)
|
if ((card = find_card(this, card_nr)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
access = check_access(this, card);
|
process_card(this, ACTION_CHANGE, card);
|
||||||
if (access && !card->emitted)
|
|
||||||
process_card(this, ACTION_ADD, card);
|
|
||||||
else if (!access && card->emitted)
|
|
||||||
process_card(this, ACTION_DISABLE, card);
|
|
||||||
}
|
}
|
||||||
/* /dev/snd/ might have been removed */
|
/* /dev/snd/ might have been removed */
|
||||||
if ((event->mask & (IN_IGNORED | IN_MOVE_SELF)))
|
if ((event->mask & (IN_IGNORED | IN_MOVE_SELF)))
|
||||||
|
|
@ -915,7 +901,7 @@ static void impl_on_fd_events(struct spa_source *source)
|
||||||
start_inotify(this);
|
start_inotify(this);
|
||||||
|
|
||||||
if (spa_streq(action, "change")) {
|
if (spa_streq(action, "change")) {
|
||||||
process_udev_device(this, ACTION_ADD, udev_device);
|
process_udev_device(this, ACTION_CHANGE, udev_device);
|
||||||
} else if (spa_streq(action, "remove")) {
|
} else if (spa_streq(action, "remove")) {
|
||||||
process_udev_device(this, ACTION_REMOVE, udev_device);
|
process_udev_device(this, ACTION_REMOVE, udev_device);
|
||||||
}
|
}
|
||||||
|
|
@ -988,7 +974,7 @@ static int enum_cards(struct impl *this)
|
||||||
if (udev_device == NULL)
|
if (udev_device == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
process_udev_device(this, ACTION_ADD, udev_device);
|
process_udev_device(this, ACTION_CHANGE, udev_device);
|
||||||
|
|
||||||
udev_device_unref(udev_device);
|
udev_device_unref(udev_device);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,8 @@
|
||||||
#define MAX_DEVICES 64
|
#define MAX_DEVICES 64
|
||||||
|
|
||||||
enum action {
|
enum action {
|
||||||
ACTION_ADD,
|
ACTION_CHANGE,
|
||||||
ACTION_REMOVE,
|
ACTION_REMOVE,
|
||||||
ACTION_DISABLE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct device {
|
struct device {
|
||||||
|
|
@ -362,10 +361,14 @@ static bool check_access(struct impl *this, struct device *device)
|
||||||
static void process_device(struct impl *this, enum action action, struct device *device)
|
static void process_device(struct impl *this, enum action action, struct device *device)
|
||||||
{
|
{
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ACTION_ADD:
|
case ACTION_CHANGE:
|
||||||
if (!check_access(this, device))
|
check_access(this, device);
|
||||||
return;
|
if (device->accessible && !device->emitted) {
|
||||||
emit_object_info(this, device);
|
emit_object_info(this, device);
|
||||||
|
} else if (!device->accessible && device->emitted) {
|
||||||
|
device->emitted = false;
|
||||||
|
spa_device_emit_object_info(&this->hooks, device->id, NULL);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_REMOVE: {
|
case ACTION_REMOVE: {
|
||||||
bool emitted = device->emitted;
|
bool emitted = device->emitted;
|
||||||
|
|
@ -377,12 +380,6 @@ static void process_device(struct impl *this, enum action action, struct device
|
||||||
spa_device_emit_object_info(&this->hooks, id, NULL);
|
spa_device_emit_object_info(&this->hooks, id, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_DISABLE:
|
|
||||||
if (device->emitted) {
|
|
||||||
device->emitted = false;
|
|
||||||
spa_device_emit_object_info(&this->hooks, device->id, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -395,7 +392,7 @@ static void process_udev_device(struct impl *this, enum action action, struct ud
|
||||||
return;
|
return;
|
||||||
|
|
||||||
device = find_device(this, id);
|
device = find_device(this, id);
|
||||||
if (action == ACTION_ADD && !device)
|
if (action == ACTION_CHANGE && !device)
|
||||||
device = add_device(this, id, udev_device);
|
device = add_device(this, id, udev_device);
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
|
|
@ -453,13 +450,8 @@ static void impl_on_notify_events(struct spa_source *source)
|
||||||
if (!device)
|
if (!device)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (event->mask & IN_ATTRIB) {
|
if (event->mask & IN_ATTRIB)
|
||||||
bool access = check_access(this, device);
|
process_device(this, ACTION_CHANGE, device);
|
||||||
if (access && !device->emitted)
|
|
||||||
process_device(this, ACTION_ADD, device);
|
|
||||||
else if (!access && device->emitted)
|
|
||||||
process_device(this, ACTION_DISABLE, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->mask & IN_IGNORED)
|
if (event->mask & IN_IGNORED)
|
||||||
device->inotify_wd = -1;
|
device->inotify_wd = -1;
|
||||||
|
|
@ -510,7 +502,7 @@ static void impl_on_fd_events(struct spa_source *source)
|
||||||
|
|
||||||
if (spa_streq(action, "add") ||
|
if (spa_streq(action, "add") ||
|
||||||
spa_streq(action, "change")) {
|
spa_streq(action, "change")) {
|
||||||
process_udev_device(this, ACTION_ADD, dev);
|
process_udev_device(this, ACTION_CHANGE, dev);
|
||||||
} else if (spa_streq(action, "remove")) {
|
} else if (spa_streq(action, "remove")) {
|
||||||
process_udev_device(this, ACTION_REMOVE, dev);
|
process_udev_device(this, ACTION_REMOVE, dev);
|
||||||
}
|
}
|
||||||
|
|
@ -582,7 +574,7 @@ static int enum_devices(struct impl *this)
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
process_udev_device(this, ACTION_ADD, dev);
|
process_udev_device(this, ACTION_CHANGE, dev);
|
||||||
|
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue