spa: alsa,v4l2: avoid double lookup on inotify events

Split up `process_{device,card}()` to have a separate function that does
the lookup based on the udev device, and only use that when there is
no available reference to the actual device/card object.

(cherry picked from commit 69f9e75458)
This commit is contained in:
Barnabás Pőcze 2024-01-09 18:00:36 +01:00 committed by Robert Mader
parent d9fd1d4b28
commit e19d9784cf
2 changed files with 61 additions and 59 deletions

View file

@ -720,29 +720,16 @@ static bool check_access(struct impl *this, struct card *card)
return card->accessible;
}
static void process_card(struct impl *this, enum action action, struct udev_device *udev_device)
static void process_card(struct impl *this, enum action action, struct card *card)
{
unsigned int card_nr;
struct card *card;
bool emitted;
int res;
if ((card_nr = get_card_nr(this, udev_device)) == SPA_ID_INVALID)
return;
card = find_card(this, card_nr);
if (card && card->ignored)
if (card->ignored)
return;
switch (action) {
case ACTION_ADD:
if (card == NULL)
card = add_card(this, card_nr, udev_device);
if (card == NULL)
return;
case ACTION_ADD: {
if (!check_access(this, card))
return;
res = emit_added_object_info(this, card);
int res = emit_added_object_info(this, card);
if (res < 0) {
if (card->ignored)
spa_log_info(this->log, "ALSA card %u unavailable (%s): it is ignored",
@ -761,16 +748,12 @@ static void process_card(struct impl *this, enum action action, struct udev_devi
card->unavailable = false;
}
break;
}
case ACTION_REMOVE: {
uint32_t pcm_device_id, compress_offload_device_id;
uint32_t pcm_device_id = card->pcm_device_id;
uint32_t compress_offload_device_id = card->compress_offload_device_id;
bool emitted = card->emitted;
if (card == NULL)
return;
emitted = card->emitted;
pcm_device_id = card->pcm_device_id;
compress_offload_device_id = card->compress_offload_device_id;
remove_card(this, card);
if (emitted) {
@ -783,8 +766,6 @@ static void process_card(struct impl *this, enum action action, struct udev_devi
}
case ACTION_DISABLE:
if (card == NULL)
return;
if (card->emitted) {
uint32_t pcm_device_id, compress_offload_device_id;
@ -802,6 +783,24 @@ static void process_card(struct impl *this, enum action action, struct udev_devi
}
}
static void process_udev_device(struct impl *this, enum action action, struct udev_device *udev_device)
{
unsigned int card_nr;
struct card *card;
if ((card_nr = get_card_nr(this, udev_device)) == SPA_ID_INVALID)
return;
card = find_card(this, card_nr);
if (action == ACTION_ADD && !card)
card = add_card(this, card_nr, udev_device);
if (!card)
return;
process_card(this, action, card);
}
static int stop_inotify(struct impl *this)
{
if (this->notify.fd == -1)
@ -854,9 +853,9 @@ static void impl_on_notify_events(struct spa_source *source)
access = check_access(this, card);
if (access && !card->emitted)
process_card(this, ACTION_ADD, card->udev_device);
process_card(this, ACTION_ADD, card);
else if (!access && card->emitted)
process_card(this, ACTION_DISABLE, card->udev_device);
process_card(this, ACTION_DISABLE, card);
}
/* /dev/snd/ might have been removed */
if ((event->mask & (IN_IGNORED | IN_MOVE_SELF)))
@ -919,9 +918,9 @@ static void impl_on_fd_events(struct spa_source *source)
start_inotify(this);
if (spa_streq(action, "change")) {
process_card(this, ACTION_ADD, udev_device);
process_udev_device(this, ACTION_ADD, udev_device);
} else if (spa_streq(action, "remove")) {
process_card(this, ACTION_REMOVE, udev_device);
process_udev_device(this, ACTION_REMOVE, udev_device);
}
udev_device_unref(udev_device);
}
@ -992,7 +991,7 @@ static int enum_cards(struct impl *this)
if (udev_device == NULL)
continue;
process_card(this, ACTION_ADD, udev_device);
process_udev_device(this, ACTION_ADD, udev_device);
udev_device_unref(udev_device);
}

View file

@ -359,48 +359,51 @@ static bool check_access(struct impl *this, struct device *device)
return device->accessible;
}
static void process_device(struct impl *this, enum action action, struct udev_device *dev)
static void process_device(struct impl *this, enum action action, struct device *device)
{
uint32_t id;
struct device *device;
bool emitted;
if ((id = get_device_id(this, dev)) == SPA_ID_INVALID)
return;
device = find_device(this, id);
switch (action) {
case ACTION_ADD:
if (device == NULL)
device = add_device(this, id, dev);
if (device == NULL)
return;
if (!check_access(this, device))
return;
emit_object_info(this, device);
break;
case ACTION_REMOVE: {
bool emitted = device->emitted;
uint32_t id = device->id;
case ACTION_REMOVE:
if (device == NULL)
return;
emitted = device->emitted;
remove_device(this, device);
if (emitted)
spa_device_emit_object_info(&this->hooks, id, NULL);
break;
}
case ACTION_DISABLE:
if (device == NULL)
return;
if (device->emitted) {
device->emitted = false;
spa_device_emit_object_info(&this->hooks, id, NULL);
spa_device_emit_object_info(&this->hooks, device->id, NULL);
}
break;
}
}
static void process_udev_device(struct impl *this, enum action action, struct udev_device *udev_device)
{
struct device *device;
uint32_t id;
if ((id = get_device_id(this, udev_device)) == SPA_ID_INVALID)
return;
device = find_device(this, id);
if (action == ACTION_ADD && !device)
device = add_device(this, id, udev_device);
if (!device)
return;
process_device(this, action, device);
}
static int stop_inotify(struct impl *this)
{
if (this->notify.fd == -1)
@ -453,9 +456,9 @@ static void impl_on_notify_events(struct spa_source *source)
bool access = check_access(this, device);
if (access && !device->emitted)
process_device(this, ACTION_ADD, device->dev);
process_device(this, ACTION_ADD, device);
else if (!access && device->emitted)
process_device(this, ACTION_DISABLE, device->dev);
process_device(this, ACTION_DISABLE, device);
}
}
}
@ -504,9 +507,9 @@ static void impl_on_fd_events(struct spa_source *source)
if (spa_streq(action, "add") ||
spa_streq(action, "change")) {
process_device(this, ACTION_ADD, dev);
process_udev_device(this, ACTION_ADD, dev);
} else if (spa_streq(action, "remove")) {
process_device(this, ACTION_REMOVE, dev);
process_udev_device(this, ACTION_REMOVE, dev);
}
udev_device_unref(dev);
}
@ -576,7 +579,7 @@ static int enum_devices(struct impl *this)
if (dev == NULL)
continue;
process_device(this, ACTION_ADD, dev);
process_udev_device(this, ACTION_ADD, dev);
udev_device_unref(dev);
}