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.
This commit is contained in:
Barnabás Pőcze 2024-01-09 18:00:36 +01:00
parent 57a5417703
commit 69f9e75458
2 changed files with 61 additions and 59 deletions

View file

@ -717,29 +717,16 @@ static bool check_access(struct impl *this, struct card *card)
return card->accessible; 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; if (card->ignored)
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)
return; return;
switch (action) { switch (action) {
case ACTION_ADD: case ACTION_ADD: {
if (card == NULL)
card = add_card(this, card_nr, udev_device);
if (card == NULL)
return;
if (!check_access(this, card)) if (!check_access(this, card))
return; return;
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",
@ -758,16 +745,12 @@ static void process_card(struct impl *this, enum action action, struct udev_devi
card->unavailable = false; card->unavailable = false;
} }
break; break;
}
case ACTION_REMOVE: { 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); remove_card(this, card);
if (emitted) { if (emitted) {
@ -780,8 +763,6 @@ static void process_card(struct impl *this, enum action action, struct udev_devi
} }
case ACTION_DISABLE: case ACTION_DISABLE:
if (card == NULL)
return;
if (card->emitted) { if (card->emitted) {
uint32_t pcm_device_id, compress_offload_device_id; uint32_t pcm_device_id, compress_offload_device_id;
@ -799,6 +780,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) static int stop_inotify(struct impl *this)
{ {
if (this->notify.fd == -1) if (this->notify.fd == -1)
@ -851,9 +850,9 @@ static void impl_on_notify_events(struct spa_source *source)
access = check_access(this, card); access = check_access(this, card);
if (access && !card->emitted) if (access && !card->emitted)
process_card(this, ACTION_ADD, card->udev_device); process_card(this, ACTION_ADD, card);
else if (!access && card->emitted) 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 */ /* /dev/snd/ might have been removed */
if ((event->mask & (IN_IGNORED | IN_MOVE_SELF))) if ((event->mask & (IN_IGNORED | IN_MOVE_SELF)))
@ -916,9 +915,9 @@ 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_card(this, ACTION_ADD, udev_device); process_udev_device(this, ACTION_ADD, udev_device);
} else if (spa_streq(action, "remove")) { } 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); udev_device_unref(udev_device);
} }
@ -989,7 +988,7 @@ static int enum_cards(struct impl *this)
if (udev_device == NULL) if (udev_device == NULL)
continue; continue;
process_card(this, ACTION_ADD, udev_device); process_udev_device(this, ACTION_ADD, udev_device);
udev_device_unref(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; 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) { switch (action) {
case ACTION_ADD: case ACTION_ADD:
if (device == NULL)
device = add_device(this, id, dev);
if (device == NULL)
return;
if (!check_access(this, device)) if (!check_access(this, device))
return; return;
emit_object_info(this, device); emit_object_info(this, device);
break; 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); remove_device(this, device);
if (emitted) if (emitted)
spa_device_emit_object_info(&this->hooks, id, NULL); spa_device_emit_object_info(&this->hooks, id, NULL);
break; break;
}
case ACTION_DISABLE: case ACTION_DISABLE:
if (device == NULL)
return;
if (device->emitted) { if (device->emitted) {
device->emitted = false; device->emitted = false;
spa_device_emit_object_info(&this->hooks, id, NULL); spa_device_emit_object_info(&this->hooks, device->id, NULL);
} }
break; 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) static int stop_inotify(struct impl *this)
{ {
if (this->notify.fd == -1) 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); bool access = check_access(this, device);
if (access && !device->emitted) if (access && !device->emitted)
process_device(this, ACTION_ADD, device->dev); process_device(this, ACTION_ADD, device);
else if (!access && device->emitted) 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") || if (spa_streq(action, "add") ||
spa_streq(action, "change")) { spa_streq(action, "change")) {
process_device(this, ACTION_ADD, dev); process_udev_device(this, ACTION_ADD, dev);
} else if (spa_streq(action, "remove")) { } else if (spa_streq(action, "remove")) {
process_device(this, ACTION_REMOVE, dev); process_udev_device(this, ACTION_REMOVE, dev);
} }
udev_device_unref(dev); udev_device_unref(dev);
} }
@ -576,7 +579,7 @@ static int enum_devices(struct impl *this)
if (dev == NULL) if (dev == NULL)
continue; continue;
process_device(this, ACTION_ADD, dev); process_udev_device(this, ACTION_ADD, dev);
udev_device_unref(dev); udev_device_unref(dev);
} }