[tracker/arg0filter-for-store] Implement a arg0 filter for tracker-store too, however:



commit 747b48d054044ddb9b298da0d3eb2af7bfc7fcb3
Author: Philip Van Hoof <philip codeminded be>
Date:   Wed Sep 15 11:47:27 2010 +0200

    Implement a arg0 filter for tracker-store too, however:
    
    This doesn't make much sense as it causes a AddMatch and RemoveMatch
    DBus call per client that connects. Letting tracker-store wakeup on
    each NameOwnerChanged but not making it do the AddMatch and RemoveMatch
    each query or insert/delete query is probably a better idea anyway.

 src/libtracker-miner/tracker-dbus.c |    6 ++
 src/tracker-store/tracker-dbus.c    |  135 +++++++++++++++++++++++++----------
 src/tracker-store/tracker-dbus.h    |    4 +-
 src/tracker-store/tracker-store.c   |   18 ++++-
 4 files changed, 122 insertions(+), 41 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-dbus.c b/src/libtracker-miner/tracker-dbus.c
index f9b12bd..09d7417 100644
--- a/src/libtracker-miner/tracker-dbus.c
+++ b/src/libtracker-miner/tracker-dbus.c
@@ -30,6 +30,7 @@ typedef struct {
 	DBusGConnection *connection;
 	DBusGProxy *gproxy;
 	GHashTable *name_monitors;
+	TrackerMiner *miner; /* weak */
 } DBusData;
 
 static GQuark dbus_data = 0;
@@ -179,6 +180,10 @@ dbus_data_destroy (gpointer data)
 
 	dd = data;
 
+	/* dd->miner is weak */
+	dbus_connection_remove_filter (dbus_g_connection_get_connection (dd->connection),
+	                               message_filter, dd->miner);
+
 	if (dd->gproxy) {
 		g_object_unref (dd->gproxy);
 	}
@@ -250,6 +255,7 @@ dbus_data_create (TrackerMiner          *miner,
 	data = g_slice_new0 (DBusData);
 	/* Connection object is a shared one, so we need to keep our own
 	 * reference to it */
+	data->miner = miner;
 	data->connection = dbus_g_connection_ref (connection);
 	data->gproxy = gproxy;
 	data->name_monitors = g_hash_table_new_full (g_str_hash,
diff --git a/src/tracker-store/tracker-dbus.c b/src/tracker-store/tracker-dbus.c
index b568015..8b06f23 100644
--- a/src/tracker-store/tracker-dbus.c
+++ b/src/tracker-store/tracker-dbus.c
@@ -49,6 +49,8 @@ static DBusGProxy      *gproxy;
 static GSList          *objects;
 static TrackerStatus   *notifier;
 static TrackerBackup   *backup;
+static GQuark           dbus_interface_quark = 0;
+static GQuark           name_owner_changed_signal_quark = 0;
 #ifdef HAVE_DBUS_FD_PASSING
 static TrackerSteroids *steroids;
 #endif
@@ -112,6 +114,49 @@ tracker_dbus_register_names (void)
 	return TRUE;
 }
 
+static void
+name_owner_changed_cb (const gchar *name,
+                       const gchar *old_owner,
+                       const gchar *new_owner,
+                       gpointer     user_data)
+{
+	if (tracker_is_empty_string (new_owner) && !tracker_is_empty_string (old_owner)) {
+		/* This means that old_owner got removed */
+		tracker_resources_unreg_batches (user_data, old_owner);
+	}
+}
+
+static DBusHandlerResult
+message_filter (DBusConnection *connection,
+                DBusMessage    *message,
+                gpointer        user_data)
+{
+	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);
+		}
+	}
+
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
 gboolean
 tracker_dbus_init (void)
 {
@@ -149,32 +194,55 @@ tracker_dbus_init (void)
 	                                    DBUS_PATH_DBUS,
 	                                    DBUS_INTERFACE_DBUS);
 
-	dbus_g_proxy_add_signal (gproxy, "NameOwnerChanged",
-	                         G_TYPE_STRING,
-	                         G_TYPE_STRING,
-	                         G_TYPE_STRING,
-	                         G_TYPE_INVALID);
+	dbus_interface_quark = g_quark_from_static_string ("org.freedesktop.DBus");
+	name_owner_changed_signal_quark = g_quark_from_static_string ("NameOwnerChanged");
+
+	dbus_connection_add_filter (dbus_g_connection_get_connection (connection),
+	                            message_filter, NULL, NULL);
 
 	return TRUE;
 }
 
-static void
-name_owner_changed_cb (DBusGProxy *proxy,
-                       gchar      *name,
-                       gchar      *old_owner,
-                       gchar      *new_owner,
-                       gpointer    user_data)
+static gchar *
+get_name_owner_changed_match_rule (const gchar *name)
 {
-	if (tracker_is_empty_string (new_owner) && !tracker_is_empty_string (old_owner)) {
-		/* This means that old_owner got removed */
-		tracker_resources_unreg_batches (user_data, old_owner);
+	return g_strdup_printf ("type='signal',"
+	                        "sender='" DBUS_SERVICE_DBUS "',"
+	                        "interface='" DBUS_INTERFACE_DBUS "',"
+	                        "path='" DBUS_PATH_DBUS "',"
+	                        "member='NameOwnerChanged',"
+	                        "arg0='%s'", name);
+}
+
+void
+tracker_dbus_add_name_watch (const gchar *name)
+{
+	gchar *match_rule;
+
+	g_return_if_fail (connection != NULL);
+
+	match_rule = get_name_owner_changed_match_rule (name);
+	dbus_bus_add_match (dbus_g_connection_get_connection (connection),
+	                    match_rule, NULL);
+	if (!dbus_bus_name_has_owner (dbus_g_connection_get_connection (connection),
+	                              name, NULL)) {
+		/* Ops, the name went away before we could receive NameOwnerChanged for it */
+		name_owner_changed_cb ("", name, name, NULL);
 	}
+	g_free (match_rule);
 }
 
-static void
-name_owner_changed_closure (gpointer  data,
-                            GClosure *closure)
+void
+tracker_dbus_remove_name_watch (const gchar *name)
 {
+	gchar *match_rule;
+
+	g_return_if_fail (connection != NULL);
+
+	match_rule = get_name_owner_changed_match_rule (name);
+	dbus_bus_remove_match (dbus_g_connection_get_connection (connection),
+	                       match_rule, NULL);
+	g_free (match_rule);
 }
 
 static void
@@ -185,32 +253,25 @@ dbus_set_available (gboolean available)
 			tracker_dbus_register_objects ();
 		}
 	} else {
-                GSList *l;
-
-                if (objects) {
-                        dbus_g_proxy_disconnect_signal (gproxy,
-                                                        "NameOwnerChanged",
-                                                        G_CALLBACK (name_owner_changed_cb),
-                                                        tracker_dbus_get_object (TRACKER_TYPE_RESOURCES));
-                }
+		GSList *l;
 
 #ifdef HAVE_DBUS_FD_PASSING
-                if (steroids) {
+		if (steroids) {
 			dbus_connection_remove_filter (dbus_g_connection_get_connection (connection),
 			                               tracker_steroids_connection_filter,
 			                               steroids);
 			g_object_unref (steroids);
 			steroids = NULL;
-                }
+		}
 #endif
 
-                for (l = objects; l; l = l->next) {
-                        dbus_g_connection_unregister_g_object (connection, l->data);
-                        g_object_unref (l->data);
-                }
+		for (l = objects; l; l = l->next) {
+			dbus_g_connection_unregister_g_object (connection, l->data);
+			g_object_unref (l->data);
+		}
 
-                g_slist_free (objects);
-                objects = NULL;
+		g_slist_free (objects);
+		objects = NULL;
 	}
 }
 
@@ -219,6 +280,9 @@ tracker_dbus_shutdown (void)
 {
 	dbus_set_available (FALSE);
 
+	dbus_connection_remove_filter (dbus_g_connection_get_connection (connection),
+	                               message_filter, NULL);
+
 	if (backup) {
 		dbus_g_connection_unregister_g_object (connection, G_OBJECT (backup));
 		g_object_unref (backup);
@@ -292,11 +356,6 @@ tracker_dbus_register_objects (void)
 		return FALSE;
 	}
 
-	dbus_g_proxy_connect_signal (gproxy, "NameOwnerChanged",
-	                             G_CALLBACK (name_owner_changed_cb),
-	                             object,
-	                             name_owner_changed_closure);
-
 	dbus_register_object (connection,
 	                      gproxy,
 	                      G_OBJECT (object),
diff --git a/src/tracker-store/tracker-dbus.h b/src/tracker-store/tracker-dbus.h
index 541b9e3..3ea6bcb 100644
--- a/src/tracker-store/tracker-dbus.h
+++ b/src/tracker-store/tracker-dbus.h
@@ -32,10 +32,12 @@ G_BEGIN_DECLS
 gboolean        tracker_dbus_init                          (void);
 void            tracker_dbus_shutdown                      (void);
 gboolean        tracker_dbus_register_objects              (void);
-GObject        *tracker_dbus_get_object                    (GType type);
+GObject        *tracker_dbus_get_object                    (GType        type);
 TrackerStatus  *tracker_dbus_register_notifier             (void);
 gboolean        tracker_dbus_register_names                (void);
 gboolean        tracker_dbus_register_prepare_class_signal (void);
+void            tracker_dbus_add_name_watch                (const gchar *name);
+void            tracker_dbus_remove_name_watch             (const gchar *name);
 
 G_END_DECLS
 
diff --git a/src/tracker-store/tracker-store.c b/src/tracker-store/tracker-store.c
index 7d10695..fda35ce 100644
--- a/src/tracker-store/tracker-store.c
+++ b/src/tracker-store/tracker-store.c
@@ -39,6 +39,7 @@
 
 #include "tracker-store.h"
 #include "tracker-events.h"
+#include "tracker-dbus.h"
 
 #define TRACKER_STORE_MAX_CONCURRENT_QUERIES               2
 
@@ -327,6 +328,10 @@ task_finish_cb (gpointer data)
 		task->destroy (task->user_data);
 	}
 
+	if (task->client_id) {
+		tracker_dbus_remove_name_watch (task->client_id);
+	}
+
 	store_task_free (task);
 
 	sched (private);
@@ -484,6 +489,7 @@ tracker_store_sparql_query (const gchar *sparql,
 	task->callback.query.in_thread = in_thread;
 	task->destroy = destroy;
 	task->client_id = g_strdup (client_id);
+	tracker_dbus_add_name_watch (task->client_id);
 
 	g_queue_push_tail (private->query_queues[priority], task);
 
@@ -513,6 +519,7 @@ tracker_store_sparql_update (const gchar *sparql,
 	task->callback.update_callback = callback;
 	task->destroy = destroy;
 	task->client_id = g_strdup (client_id);
+	tracker_dbus_add_name_watch (task->client_id);
 
 	g_queue_push_tail (private->update_queues[priority], task);
 
@@ -542,6 +549,7 @@ tracker_store_sparql_update_blank (const gchar *sparql,
 	task->callback.update_blank_callback = callback;
 	task->destroy = destroy;
 	task->client_id = g_strdup (client_id);
+	tracker_dbus_add_name_watch (task->client_id);
 
 	g_queue_push_tail (private->update_queues[priority], task);
 
@@ -570,6 +578,7 @@ tracker_store_queue_turtle_import (GFile                      *file,
 	task->callback.update_callback = callback;
 	task->destroy = destroy;
 	task->client_id = g_strdup (client_id);
+	tracker_dbus_add_name_watch (task->client_id);
 
 	g_queue_push_tail (private->update_queues[TRACKER_STORE_PRIORITY_TURTLE], task);
 
@@ -606,8 +615,13 @@ unreg_task (TrackerStoreTask *task,
 	} else if (task->type == TRACKER_STORE_TASK_TYPE_TURTLE) {
 		task->callback.turtle_callback (error, task->user_data);
 	}
+
 	task->destroy (task->user_data);
 
+	if (task->client_id) {
+		tracker_dbus_remove_name_watch (task->client_id);
+	}
+
 	store_task_free (task);
 }
 
@@ -650,7 +664,7 @@ tracker_store_unreg_batches (const gchar *client_id)
 
 				if (!error) {
 					g_set_error (&error, TRACKER_DBUS_ERROR, 0,
-						     "Client disappeared");
+					             "Client disappeared");
 				}
 
 				unreg_task (task, error);
@@ -671,7 +685,7 @@ tracker_store_unreg_batches (const gchar *client_id)
 
 				if (!error) {
 					g_set_error (&error, TRACKER_DBUS_ERROR, 0,
-						     "Client disappeared");
+					             "Client disappeared");
 				}
 
 				unreg_task (task, error);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]