[pulseaudio-discuss] [PATCH reserve 2/2] Initialize monitor's busy status to false if we own the device.

David Henningsson david.henningsson at canonical.com
Tue Jan 15 00:50:19 PST 2013


On 01/12/2013 07:22 PM, Tanu Kaskinen wrote:
> Bug found by David Henningsson.
> ---
>   reserve-monitor.c |   74 +++++++++++++++++++++++++++++++++++++++++++----------
>   1 file changed, 60 insertions(+), 14 deletions(-)
>
> diff --git a/reserve-monitor.c b/reserve-monitor.c
> index 4097a6f..39a0c77 100644
> --- a/reserve-monitor.c
> +++ b/reserve-monitor.c
> @@ -59,6 +59,22 @@ struct rm_monitor {
>   	"member='NameOwnerChanged',"		\
>   	"arg0='%s'"
>
> +static unsigned get_busy(
> +	DBusConnection *c,
> +	const char *name_owner) {
> +
> +	const char *un;
> +
> +	if (!name_owner || !*name_owner)
> +		return FALSE;
> +
> +	if ((un = dbus_bus_get_unique_name(c)))
> +		if (strcmp(name_owner, un) == 0)
> +			return FALSE;
> +
> +	return TRUE;
> +}
> +
>   static DBusHandlerResult filter_handler(
>   	DBusConnection *c,
>   	DBusMessage *s,
> @@ -87,16 +103,7 @@ static DBusHandlerResult filter_handler(
>   		if (strcmp(name, m->service_name) == 0) {
>   			unsigned old_busy = m->busy;
>
> -			m->busy = !!(new && *new);
> -
> -			/* If we ourselves own the device, then don't consider this 'busy' */

This comment got lost. Should be moved to the get_busy function

> -			if (m->busy) {
> -				const char *un;
> -
> -				if ((un = dbus_bus_get_unique_name(c)))
> -					if (strcmp(new, un) == 0)
> -						m->busy = FALSE;
> -			}
> +			m->busy = get_busy(c, new);
>
>   			if (m->busy != old_busy && m->change_cb) {
>   				m->ref++;
> @@ -115,11 +122,13 @@ invalid:
>   int rm_watch(
>   	rm_monitor **_m,
>   	DBusConnection *connection,
> -	const char*device_name,
> +	const char *device_name,
>   	rm_change_cb_t change_cb,
>   	DBusError *error)  {
>
>   	rm_monitor *m = NULL;
> +	DBusMessage *msg = NULL, *reply = NULL;
> +	const char *name_owner;
>   	int r;
>   	DBusError _error;
>
> @@ -178,13 +187,44 @@ int rm_watch(
>
>   	m->matching = 1;
>
> -	m->busy = dbus_bus_name_has_owner(m->connection, m->service_name, error);
> +	if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetNameOwner"))) {
> +		r = -ENOMEM;
> +		goto fail;
> +	}

The rm_watch function is long enough already - I'd prefer if you move 
the new code to a separate get_name_ower function (even if that would 
mean a strdup).

>
> -	if (dbus_error_is_set(error)) {
> -		r = -EIO;
> +	if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &m->service_name, DBUS_TYPE_INVALID)) {
> +		r = -ENOMEM;
>   		goto fail;
>   	}
>
> +	reply = dbus_connection_send_with_reply_and_block(m->connection, msg, DBUS_TIMEOUT_USE_DEFAULT, error);
> +	dbus_message_unref(msg);
> +	msg = NULL;
> +
> +	if (reply) {
> +		if (!dbus_message_get_args(reply, error, DBUS_TYPE_STRING, &name_owner, DBUS_TYPE_INVALID)) {
> +			r = -EIO;
> +			goto fail;
> +		}
> +	} else {
> +		if (dbus_error_has_name(error, "org.freedesktop.DBus.Error.NameHasNoOwner")) {
> +			dbus_error_free(error);
> +			name_owner = NULL;
> +		} else {
> +			r = -EIO;
> +			goto fail;
> +		}
> +	}
> +
> +	m->busy = get_busy(m->connection, name_owner);
> +
> +	/* The reply can't be unreffed earlier, because name_owner points
> +	 * inside the message. */
> +	if (reply) {
> +		dbus_message_unref(reply);
> +		reply = NULL;
> +	}
> +
>   	*_m = m;
>   	return 0;
>
> @@ -192,6 +232,12 @@ fail:
>   	if (&_error == error)
>   		dbus_error_free(&_error);
>
> +	if (msg)
> +		dbus_message_unref(msg);
> +
> +	if (reply)
> +		dbus_message_unref(reply);
> +
>   	if (m)
>   		rm_release(m);
>
>



-- 
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic


More information about the pulseaudio-discuss mailing list