alsa-mixer: fix the re-attach code for the mixer control element

The new helem must be tracked and old helem must be cleared
to make the code work properly. Introduce the pointer to helem
as the private value for melem and add the necessary code.

Also, add a check for the duplicate mixer elements. The duplicate
mixer element invokes the abort check in alsa-lib. Print a warning
instead and handle the exit gracefully.

Fixes: def8eb074 ("alsa-mixer: allow to re-attach the mixer control element")
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Wim Taymans 2023-03-20 17:47:52 +01:00
parent 97b99a0f7c
commit 815e8c8fa0
2 changed files with 51 additions and 10 deletions

View file

@ -608,7 +608,7 @@ struct temp_port_avail {
static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask)
{
pa_card *impl = snd_mixer_elem_get_callback_private(melem);
snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem);
snd_hctl_elem_t **_elem = snd_mixer_elem_get_private(melem), *elem;
snd_ctl_elem_value_t *elem_value;
bool plugged_in, any_input_port_available;
void *state;
@ -618,6 +618,8 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask)
enum acp_available active_available = ACP_AVAILABLE_UNKNOWN;
size_t size;
pa_assert(_elem);
elem = *_elem;
#if 0
/* Changing the jack state may cause a port change, and a port change will
* make the sink or source change the mixer settings. If there are multiple
@ -886,13 +888,17 @@ static pa_device_port* find_port_with_eld_device(pa_card *impl, int device)
static int hdmi_eld_changed(snd_mixer_elem_t *melem, unsigned int mask)
{
pa_card *impl = snd_mixer_elem_get_callback_private(melem);
snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem);
int device = snd_hctl_elem_get_device(elem);
snd_hctl_elem_t **_elem = snd_mixer_elem_get_private(melem), *elem;
int device;
const char *old_monitor_name;
pa_device_port *p;
pa_hdmi_eld eld;
bool changed = false;
pa_assert(_elem);
elem = *_elem;
device = snd_hctl_elem_get_device(elem);
if (mask == SND_CTL_EVENT_MASK_REMOVE)
return 0;