mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
reserve: Fix leaking NameLost signals after release+acquire
The use of the pseudo-blocking D-Bus calls leads to the problem that NameLost signals are received after the reply to ReleaseName(). The problem with this is that a later acquisition of the same audio device can potentially receive the NameLost signal corresponding to the previous instance, due to the fact that the signal hasn't been popped from the D-Bus message queue. The simplest approach to solve this problem is to poll the actual name owner from the D-Bus daemon, in order to make sure that we did really lose the name. The proposal uses a blocking call to GetNameOwner to avoid incosistent states in the internal APIs: it would otherwise be possible to have a "busy" device before the reservation has been lost, in the unlikely case if some other process acquires the name before we got the confirmation that the NameLost was actually true.
This commit is contained in:
parent
88a7b31ca7
commit
1db09d3013
1 changed files with 17 additions and 0 deletions
|
|
@ -293,6 +293,7 @@ static DBusHandlerResult filter_handler(
|
|||
|
||||
rd_device *d;
|
||||
DBusError error;
|
||||
char *name_owner = NULL;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
|
|
@ -310,6 +311,21 @@ static DBusHandlerResult filter_handler(
|
|||
goto invalid;
|
||||
|
||||
if (strcmp(name, d->service_name) == 0 && d->owning) {
|
||||
/* Verify the actual owner of the name to avoid leaked NameLost
|
||||
* signals from previous reservations. The D-Bus daemon will send
|
||||
* all messages asynchronously in the correct order, but we could
|
||||
* potentially process them too late due to the pseudo-blocking
|
||||
* call mechanism used during both acquisition and release. This
|
||||
* can happen if we release the device and immediately after
|
||||
* reacquire it before NameLost is processed. */
|
||||
if (!d->gave_up) {
|
||||
const char *un;
|
||||
|
||||
if ((un = dbus_bus_get_unique_name(c)) && rd_dbus_get_name_owner(c, d->service_name, &name_owner, &error) == 0)
|
||||
if (strcmp(name_owner, un) == 0)
|
||||
goto invalid; /* Name still owned by us */
|
||||
}
|
||||
|
||||
d->owning = 0;
|
||||
|
||||
if (!d->gave_up) {
|
||||
|
|
@ -326,6 +342,7 @@ static DBusHandlerResult filter_handler(
|
|||
}
|
||||
|
||||
invalid:
|
||||
free(name_owner);
|
||||
dbus_error_free(&error);
|
||||
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue