13
0

ALSA: use dedicated device reservation for probing

It can happen that the main AlsaAudioBackend::_device_reservation
is still busy while I/O devices are set. In this case a
dedicated AlsaDeviceReservation needs to be used which can fail
silently.

A common example is disconnecting a USB device while it is in
use. The Halted signal can show the session dialog, which calls
set_input_device_name before the device reservation of the
unplugged device terminated.
This commit is contained in:
Robin Gareus 2022-11-29 17:34:45 +01:00
parent 3f4feb6cc8
commit a7d2718aa4
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 11 additions and 7 deletions

View File

@ -346,10 +346,9 @@ AlsaAudioBackend::set_input_device_name (const std::string& d)
_input_audio_device_info.valid = false;
return 1;
}
_device_reservation.acquire_device (alsa_device.c_str ());
AlsaDeviceReservation adr (alsa_device.c_str ());
/* device will be busy once used, hence cache the parameters */
/* return */ get_alsa_device_parameters (alsa_device.c_str (), false, &_input_audio_device_info);
_device_reservation.release_device ();
return 0;
}
@ -380,6 +379,7 @@ AlsaAudioBackend::set_output_device_name (const std::string& d)
_output_audio_device_info.valid = false;
return 1;
}
AlsaDeviceReservation adr (alsa_device.c_str ());
/* return */ get_alsa_device_parameters (alsa_device.c_str (), true, &_output_audio_device_info);
return 0;
}
@ -2427,7 +2427,7 @@ AlsaDeviceReservation::AlsaDeviceReservation ()
AlsaDeviceReservation::AlsaDeviceReservation (const char* device_name)
: _device_reservation (0)
{
acquire_device (device_name);
acquire_device (device_name, true);
}
AlsaDeviceReservation::~AlsaDeviceReservation ()
@ -2436,7 +2436,7 @@ AlsaDeviceReservation::~AlsaDeviceReservation ()
}
bool
AlsaDeviceReservation::acquire_device (const char* device_name)
AlsaDeviceReservation::acquire_device (const char* device_name, bool silent)
{
int device_number = card_to_num (device_name);
if (device_number < 0) {
@ -2470,7 +2470,9 @@ AlsaDeviceReservation::acquire_device (const char* device_name)
_device_reservation->Terminated.connect_same_thread (_reservation_connection, boost::bind (&AlsaDeviceReservation::release_device, this));
if (_device_reservation->start (SystemExec::ShareWithParent)) {
PBD::warning << _("AlsaAudioBackend: Device Request failed.") << endmsg;
if (!silent) {
PBD::warning << _("AlsaAudioBackend: Device Request failed.") << endmsg;
}
release_device ();
return false;
}
@ -2482,7 +2484,9 @@ AlsaDeviceReservation::acquire_device (const char* device_name)
}
if (timeout == 0 || !_reservation_succeeded) {
PBD::warning << _("AlsaAudioBackend: Device Reservation failed.") << endmsg;
if (!silent) {
PBD::warning << _("AlsaAudioBackend: Device Reservation failed.") << endmsg;
}
release_device ();
return false;
}

View File

@ -106,7 +106,7 @@ class AlsaDeviceReservation
AlsaDeviceReservation (const char* device_name);
~AlsaDeviceReservation ();
bool acquire_device (const char* device_name);
bool acquire_device (const char* device_name, bool silent = false);
void release_device ();
private: