Blame SOURCES/0005-Initialize-monitor-s-busy-status-to-false-if-we-own-.patch

2b72d0
From b1691402bebfafba9c8055814493f55553f177c1 Mon Sep 17 00:00:00 2001
2b72d0
From: Tanu Kaskinen <tanuk@iki.fi>
2b72d0
Date: Wed, 16 Jan 2013 03:36:04 +0200
2b72d0
Subject: [PATCH 5/7] Initialize monitor's busy status to false if we own the
2b72d0
 device.
2b72d0
2b72d0
Bug found by David Henningsson.
2b72d0
---
2b72d0
 src/modules/reserve-monitor.c | 96 +++++++++++++++++++++++++++++++++++--------
2b72d0
 1 file changed, 80 insertions(+), 16 deletions(-)
2b72d0
2b72d0
diff --git a/src/modules/reserve-monitor.c b/src/modules/reserve-monitor.c
2b72d0
index 4097a6f..4aa4a2b 100644
2b72d0
--- a/src/modules/reserve-monitor.c
2b72d0
+++ b/src/modules/reserve-monitor.c
2b72d0
@@ -59,6 +59,23 @@ struct rm_monitor {
2b72d0
 	"member='NameOwnerChanged',"		\
2b72d0
 	"arg0='%s'"
2b72d0
 
2b72d0
+static unsigned get_busy(
2b72d0
+	DBusConnection *c,
2b72d0
+	const char *name_owner) {
2b72d0
+
2b72d0
+	const char *un;
2b72d0
+
2b72d0
+	if (!name_owner || !*name_owner)
2b72d0
+		return FALSE;
2b72d0
+
2b72d0
+	/* If we ourselves own the device, then don't consider this 'busy' */
2b72d0
+	if ((un = dbus_bus_get_unique_name(c)))
2b72d0
+		if (strcmp(name_owner, un) == 0)
2b72d0
+			return FALSE;
2b72d0
+
2b72d0
+	return TRUE;
2b72d0
+}
2b72d0
+
2b72d0
 static DBusHandlerResult filter_handler(
2b72d0
 	DBusConnection *c,
2b72d0
 	DBusMessage *s,
2b72d0
@@ -87,16 +104,7 @@ static DBusHandlerResult filter_handler(
2b72d0
 		if (strcmp(name, m->service_name) == 0) {
2b72d0
 			unsigned old_busy = m->busy;
2b72d0
 
2b72d0
-			m->busy = !!(new && *new);
2b72d0
-
2b72d0
-			/* If we ourselves own the device, then don't consider this 'busy' */
2b72d0
-			if (m->busy) {
2b72d0
-				const char *un;
2b72d0
-
2b72d0
-				if ((un = dbus_bus_get_unique_name(c)))
2b72d0
-					if (strcmp(new, un) == 0)
2b72d0
-						m->busy = FALSE;
2b72d0
-			}
2b72d0
+			m->busy = get_busy(c, new);
2b72d0
 
2b72d0
 			if (m->busy != old_busy && m->change_cb) {
2b72d0
 				m->ref++;
2b72d0
@@ -112,14 +120,71 @@ invalid:
2b72d0
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2b72d0
 }
2b72d0
 
2b72d0
+static int get_name_owner(
2b72d0
+	DBusConnection *connection,
2b72d0
+	const char *name,
2b72d0
+	char **name_owner,
2b72d0
+	DBusError *error) {
2b72d0
+
2b72d0
+	DBusMessage *msg, *reply;
2b72d0
+	int r;
2b72d0
+
2b72d0
+	*name_owner = NULL;
2b72d0
+
2b72d0
+	if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetNameOwner"))) {
2b72d0
+		r = -ENOMEM;
2b72d0
+		goto fail;
2b72d0
+	}
2b72d0
+
2b72d0
+	if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) {
2b72d0
+		r = -ENOMEM;
2b72d0
+		goto fail;
2b72d0
+	}
2b72d0
+
2b72d0
+	reply = dbus_connection_send_with_reply_and_block(connection, msg, DBUS_TIMEOUT_USE_DEFAULT, error);
2b72d0
+	dbus_message_unref(msg);
2b72d0
+	msg = NULL;
2b72d0
+
2b72d0
+	if (reply) {
2b72d0
+		if (!dbus_message_get_args(reply, error, DBUS_TYPE_STRING, name_owner, DBUS_TYPE_INVALID)) {
2b72d0
+			dbus_message_unref(reply);
2b72d0
+			r = -EIO;
2b72d0
+			goto fail;
2b72d0
+		}
2b72d0
+
2b72d0
+		*name_owner = strdup(*name_owner);
2b72d0
+		dbus_message_unref(reply);
2b72d0
+
2b72d0
+		if (!*name_owner) {
2b72d0
+			r = -ENOMEM;
2b72d0
+			goto fail;
2b72d0
+		}
2b72d0
+
2b72d0
+	} else if (dbus_error_has_name(error, "org.freedesktop.DBus.Error.NameHasNoOwner"))
2b72d0
+		dbus_error_free(error);
2b72d0
+	else {
2b72d0
+		r = -EIO;
2b72d0
+		goto fail;
2b72d0
+	}
2b72d0
+
2b72d0
+	return 0;
2b72d0
+
2b72d0
+fail:
2b72d0
+	if (msg)
2b72d0
+		dbus_message_unref(msg);
2b72d0
+
2b72d0
+	return r;
2b72d0
+}
2b72d0
+
2b72d0
 int rm_watch(
2b72d0
 	rm_monitor **_m,
2b72d0
 	DBusConnection *connection,
2b72d0
-	const char*device_name,
2b72d0
+	const char *device_name,
2b72d0
 	rm_change_cb_t change_cb,
2b72d0
 	DBusError *error)  {
2b72d0
 
2b72d0
 	rm_monitor *m = NULL;
2b72d0
+	char *name_owner;
2b72d0
 	int r;
2b72d0
 	DBusError _error;
2b72d0
 
2b72d0
@@ -178,12 +243,11 @@ int rm_watch(
2b72d0
 
2b72d0
 	m->matching = 1;
2b72d0
 
2b72d0
-	m->busy = dbus_bus_name_has_owner(m->connection, m->service_name, error);
2b72d0
-
2b72d0
-	if (dbus_error_is_set(error)) {
2b72d0
-		r = -EIO;
2b72d0
+	if ((r = get_name_owner(m->connection, m->service_name, &name_owner, error)) < 0)
2b72d0
 		goto fail;
2b72d0
-	}
2b72d0
+
2b72d0
+	m->busy = get_busy(m->connection, name_owner);
2b72d0
+	free(name_owner);
2b72d0
 
2b72d0
 	*_m = m;
2b72d0
 	return 0;
2b72d0
-- 
2b72d0
1.8.1.4
2b72d0