[tracker/harmattan-pre-signal-updates: 1301/1380] libtracker-miner: Use DBus arg0 filtering for NameOwnerChanged
- From: Martyn James Russell <mr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/harmattan-pre-signal-updates: 1301/1380] libtracker-miner: Use DBus arg0 filtering for NameOwnerChanged
- Date: Wed, 22 Sep 2010 15:43:38 +0000 (UTC)
commit 77ca41b13726208f37bec31ab1092913928f6a0d
Author: Philip Van Hoof <philip codeminded be>
Date: Tue Sep 14 17:22:14 2010 +0200
libtracker-miner: Use DBus arg0 filtering for NameOwnerChanged
Fixes NB#188031
src/libtracker-miner/tracker-dbus.c | 206 +++++++++++++++++----------
src/libtracker-miner/tracker-miner-object.c | 2 +-
2 files changed, 132 insertions(+), 76 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-dbus.c b/src/libtracker-miner/tracker-dbus.c
index be6e32b..f9b12bd 100644
--- a/src/libtracker-miner/tracker-dbus.c
+++ b/src/libtracker-miner/tracker-dbus.c
@@ -27,12 +27,14 @@
#include "tracker-miner-dbus.h"
typedef struct {
- DBusGConnection *connection;
- DBusGProxy *gproxy;
- GHashTable *name_monitors;
+ DBusGConnection *connection;
+ DBusGProxy *gproxy;
+ GHashTable *name_monitors;
} DBusData;
static GQuark dbus_data = 0;
+static GQuark dbus_interface_quark = 0;
+static GQuark name_owner_changed_signal_quark = 0;
static gboolean
dbus_register_service (DBusGProxy *proxy,
@@ -42,16 +44,16 @@ dbus_register_service (DBusGProxy *proxy,
guint result;
g_message ("Registering D-Bus service...\n"
- " Name:'%s'",
- name);
+ " Name:'%s'",
+ name);
if (!org_freedesktop_DBus_request_name (proxy,
- name,
- DBUS_NAME_FLAG_DO_NOT_QUEUE,
- &result, &error)) {
+ name,
+ DBUS_NAME_FLAG_DO_NOT_QUEUE,
+ &result, &error)) {
g_critical ("Could not acquire name:'%s', %s",
- name,
- error ? error->message : "no error given");
+ name,
+ error ? error->message : "no error given");
g_error_free (error);
return FALSE;
@@ -59,8 +61,8 @@ dbus_register_service (DBusGProxy *proxy,
if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
g_critical ("D-Bus service name:'%s' is already taken, "
- "perhaps the application is already running?",
- name);
+ "perhaps the application is already running?",
+ name);
return FALSE;
}
@@ -68,11 +70,11 @@ dbus_register_service (DBusGProxy *proxy,
}
static gboolean
-dbus_register_object (GObject *object,
- DBusGConnection *connection,
- DBusGProxy *proxy,
- const DBusGObjectInfo *info,
- const gchar *path)
+dbus_register_object (GObject *object,
+ DBusGConnection *connection,
+ DBusGProxy *proxy,
+ const DBusGObjectInfo *info,
+ const gchar *path)
{
g_message ("Registering D-Bus object...");
g_message (" Path:'%s'", path);
@@ -84,51 +86,90 @@ dbus_register_object (GObject *object,
return TRUE;
}
+static gchar *
+get_name_owner_changed_match_rule (const gchar *name)
+{
+ return g_strdup_printf ("type='signal',"
+ "sender='" DBUS_SERVICE_DBUS "',"
+ "interface='" DBUS_INTERFACE_DBUS "',"
+ "path='" DBUS_PATH_DBUS "',"
+ "member='NameOwnerChanged',"
+ "arg0='%s'", name);
+}
+
static void
-name_owner_changed_cb (DBusGProxy *proxy,
- gchar *name,
- gchar *old_owner,
- gchar *new_owner,
- gpointer user_data)
+name_owner_changed_cb (const gchar *name,
+ const gchar *old_owner,
+ const gchar *new_owner,
+ gpointer user_data)
{
TrackerMinerDBusNameFunc func;
- TrackerMiner *miner;
- gboolean available;
- DBusData *data;
+ TrackerMiner *miner;
+ gboolean available;
+ DBusData *data;
- miner = user_data;
+ miner = user_data;
- if (!name || !*name) {
- return;
- }
+ if (!name || !*name) {
+ return;
+ }
data = g_object_get_qdata (G_OBJECT (miner), dbus_data);
- if (!data) {
- return;
- }
+ if (!data) {
+ return;
+ }
- func = g_hash_table_lookup (data->name_monitors, name);
+ func = g_hash_table_lookup (data->name_monitors, name);
- if (!func) {
- return;
- }
+ if (!func) {
+ return;
+ }
available = (new_owner && *new_owner);
- (func) (miner, name, available);
+
+ (func) (miner, name, available);
+
+ if (g_strcmp0 (new_owner, "") == 0 && g_strcmp0 (name, old_owner) == 0) {
+ gchar *match_rule;
+ /* "name" disappeared from the bus and we have a registry for it */
+ g_hash_table_remove (data->name_monitors, name);
+ match_rule = get_name_owner_changed_match_rule (name);
+ dbus_bus_remove_match (dbus_g_connection_get_connection (data->connection),
+ match_rule, NULL);
+ g_free (match_rule);
+ }
}
-static void
-dbus_set_name_monitor (TrackerMiner *miner,
- DBusGProxy *proxy)
+static DBusHandlerResult
+message_filter (DBusConnection *connection,
+ DBusMessage *message,
+ gpointer user_data)
{
- dbus_g_proxy_add_signal (proxy, "NameOwnerChanged",
- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_INVALID);
+ const char *tmp;
+ GQuark interface, member;
+ int message_type;
+
+ tmp = dbus_message_get_interface (message);
+ interface = tmp ? g_quark_try_string (tmp) : 0;
+ tmp = dbus_message_get_member (message);
+ member = tmp ? g_quark_try_string (tmp) : 0;
+ message_type = dbus_message_get_type (message);
+
+ if (interface == dbus_interface_quark &&
+ message_type == DBUS_MESSAGE_TYPE_SIGNAL &&
+ member == name_owner_changed_signal_quark) {
+ const gchar *name, *prev_owner, *new_owner;
+ if (dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &prev_owner,
+ DBUS_TYPE_STRING, &new_owner,
+ DBUS_TYPE_INVALID)) {
+ name_owner_changed_cb (name, prev_owner, new_owner, user_data);
+ }
+ }
- dbus_g_proxy_connect_signal (proxy, "NameOwnerChanged",
- G_CALLBACK (name_owner_changed_cb),
- miner, NULL);
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static void
@@ -155,7 +196,7 @@ dbus_data_destroy (gpointer data)
static DBusData *
dbus_data_create (TrackerMiner *miner,
- const gchar *name,
+ const gchar *name,
const DBusGObjectInfo *info)
{
DBusData *data;
@@ -174,9 +215,9 @@ dbus_data_create (TrackerMiner *miner,
}
gproxy = dbus_g_proxy_new_for_name (connection,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS);
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
/* Register the service name for the miner */
full_name = g_strconcat (TRACKER_MINER_DBUS_NAME_PREFIX, name, NULL);
@@ -192,18 +233,19 @@ dbus_data_create (TrackerMiner *miner,
full_path = g_strconcat (TRACKER_MINER_DBUS_PATH_PREFIX, name, NULL);
if (!dbus_register_object (G_OBJECT (miner),
- connection, gproxy,
- info,
- full_path)) {
+ connection, gproxy,
+ info,
+ full_path)) {
g_object_unref (gproxy);
g_free (full_path);
return NULL;
}
- dbus_set_name_monitor (miner, gproxy);
-
g_free (full_path);
+ dbus_connection_add_filter (dbus_g_connection_get_connection (connection),
+ message_filter, miner, NULL);
+
/* Now we're successfully connected and registered, create the data */
data = g_slice_new0 (DBusData);
/* Connection object is a shared one, so we need to keep our own
@@ -223,7 +265,7 @@ _tracker_miner_dbus_init (TrackerMiner *miner,
const DBusGObjectInfo *info)
{
DBusData *data;
- gchar *name;
+ gchar *name;
g_return_if_fail (TRACKER_IS_MINER (miner));
g_return_if_fail (info != NULL);
@@ -234,19 +276,22 @@ _tracker_miner_dbus_init (TrackerMiner *miner,
data = g_object_get_qdata (G_OBJECT (miner), dbus_data);
- if (data) {
- return;
- }
+ if (data) {
+ return;
+ }
- g_object_get (miner, "name", &name, NULL);
+ g_object_get (miner, "name", &name, NULL);
if (!name) {
g_critical ("Miner '%s' should have been given a name, bailing out",
- G_OBJECT_TYPE_NAME (miner));
+ G_OBJECT_TYPE_NAME (miner));
g_assert_not_reached ();
}
- data = dbus_data_create (miner, name, info);
+ dbus_interface_quark = g_quark_from_static_string ("org.freedesktop.DBus");
+ name_owner_changed_signal_quark = g_quark_from_static_string ("NameOwnerChanged");
+
+ data = dbus_data_create (miner, name, info);
if (G_UNLIKELY (!data)) {
g_critical ("Miner could not register object on D-Bus session");
@@ -255,9 +300,9 @@ _tracker_miner_dbus_init (TrackerMiner *miner,
}
g_object_set_qdata_full (G_OBJECT (miner),
- dbus_data,
- data,
- dbus_data_destroy);
+ dbus_data,
+ data,
+ dbus_data_destroy);
g_free (name);
}
@@ -279,7 +324,8 @@ _tracker_miner_dbus_add_name_watch (TrackerMiner *miner,
const gchar *name,
TrackerMinerDBusNameFunc func)
{
- DBusData *data;
+ DBusData *data;
+ gchar *match_rule;
g_return_if_fail (TRACKER_IS_MINER (miner));
g_return_if_fail (name != NULL);
@@ -287,14 +333,24 @@ _tracker_miner_dbus_add_name_watch (TrackerMiner *miner,
data = g_object_get_qdata (G_OBJECT (miner), dbus_data);
- if (!data) {
- g_critical ("Miner '%s' was not registered on "
- "DBus, can watch for owner changes",
- G_OBJECT_TYPE_NAME (miner));
- return;
- }
+ if (!data) {
+ g_critical ("Miner '%s' was not registered on "
+ "DBus, can watch for owner changes",
+ G_OBJECT_TYPE_NAME (miner));
+ return;
+ }
- g_hash_table_insert (data->name_monitors,
- g_strdup (name),
- func);
+ g_hash_table_insert (data->name_monitors,
+ g_strdup (name),
+ func);
+
+ match_rule = get_name_owner_changed_match_rule (name);
+ dbus_bus_add_match (dbus_g_connection_get_connection (data->connection),
+ match_rule, NULL);
+ if (!dbus_bus_name_has_owner (dbus_g_connection_get_connection (data->connection),
+ name, NULL)) {
+ /* Ops, the name went away before we could receive NameOwnerChanged for it */
+ name_owner_changed_cb ("", name, name, miner);
+ }
+ g_free (match_rule);
}
diff --git a/src/libtracker-miner/tracker-miner-object.c b/src/libtracker-miner/tracker-miner-object.c
index 073fb35..8211ac8 100644
--- a/src/libtracker-miner/tracker-miner-object.c
+++ b/src/libtracker-miner/tracker-miner-object.c
@@ -371,7 +371,7 @@ miner_constructed (GObject *object)
_tracker_miner_dbus_init (miner, &dbus_glib__tracker_miner_object_info);
_tracker_miner_dbus_add_name_watch (miner, "org.freedesktop.Tracker1",
- store_name_monitor_cb);
+ store_name_monitor_cb);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]