#include <assert.h>
#include "reserve-monitor.h"
+#include "reserve.h"
struct rm_monitor {
int ref;
char *device_name;
char *service_name;
+ char *match;
DBusConnection *connection;
#define SERVICE_PREFIX "org.freedesktop.ReserveDevice1."
+#define SERVICE_FILTER \
+ "type='signal'," \
+ "sender='" DBUS_SERVICE_DBUS "'," \
+ "interface='" DBUS_INTERFACE_DBUS "'," \
+ "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 we ourselves own the device, then don't consider this 'busy' */
+ 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,
void *userdata) {
- DBusMessage *reply;
rm_monitor *m;
DBusError error;
goto invalid;
if (strcmp(name, m->service_name) == 0) {
- m->busy = !!(new && *new);
+ unsigned old_busy = m->busy;
- /* If we ourselves own the device, then don't consider this 'busy' */
- if (m->busy) {
- const char *un;
+ m->busy = get_busy(c, new);
- if ((un = dbus_bus_get_unique_name(c)))
- if (strcmp(new, un) == 0)
- m->busy = FALSE;
- }
-
- if (m->change_cb) {
+ if (m->busy != old_busy && m->change_cb) {
m->ref++;
m->change_cb(m);
rm_release(m);
}
}
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
invalid:
- if (!(reply = dbus_message_new_error(
- s,
- DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments")))
- goto oom;
-
- if (!dbus_connection_send(c, reply, NULL))
- goto oom;
-
- dbus_message_unref(reply);
-
dbus_error_free(&error);
- return DBUS_HANDLER_RESULT_HANDLED;
-
-oom:
- if (reply)
- dbus_message_unref(reply);
-
- dbus_error_free(&error);
-
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
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;
+ char *name_owner;
int r;
DBusError _error;
m->filtering = 1;
- dbus_bus_add_match(m->connection,
- "type='signal',"
- "sender='" DBUS_SERVICE_DBUS "',"
- "interface='" DBUS_INTERFACE_DBUS "',"
- "member='NameOwnerChanged'", error);
+ if (!(m->match = malloc(sizeof(SERVICE_FILTER) - 2 + strlen(m->service_name)))) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ sprintf(m->match, SERVICE_FILTER, m->service_name);
+ dbus_bus_add_match(m->connection, m->match, error);
if (dbus_error_is_set(error)) {
r = -EIO;
m->matching = 1;
- m->busy = dbus_bus_name_has_owner(m->connection, m->service_name, error);
-
- if (dbus_error_is_set(error)) {
- r = -EIO;
+ if ((r = rd_dbus_get_name_owner(m->connection, m->service_name, &name_owner, error)) < 0)
goto fail;
- }
+
+ m->busy = get_busy(m->connection, name_owner);
+ free(name_owner);
*_m = m;
return 0;
if (m->matching)
dbus_bus_remove_match(
m->connection,
- "type='signal',"
- "sender='" DBUS_SERVICE_DBUS "',"
- "interface='" DBUS_INTERFACE_DBUS "',"
- "member='NameOwnerChanged'", NULL);
+ m->match,
+ NULL);
if (m->filtering)
dbus_connection_remove_filter(
free(m->device_name);
free(m->service_name);
+ free(m->match);
if (m->connection)
dbus_connection_unref(m->connection);