[tracker/tracker-0.6] Listen for NameOwnerChanged signals for the extractor.



commit 4459cb675e323ba009ca269b9338986a0f37a50e
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Apr 15 13:12:59 2009 +0200

    Listen for NameOwnerChanged signals for the extractor.
    
    * src/tracker-indexer/tracker-dbus.[ch] (tracker_dbus_add_name_monitor)
      (tracker_dbus_remove_name_monitor): Added infrastructure for monitoring
      owner changes for certain services.
    * src/tracker-indexer/tracker-module-metadata-utils.c: Listen for changes in
      ownership of org.freedesktop.Tracker.Extract, request new PID each time the
      service becomes available.
---
 src/tracker-indexer/tracker-dbus.c                 |   89 +++++++++++++++++++-
 src/tracker-indexer/tracker-dbus.h                 |   11 ++-
 .../tracker-module-metadata-utils.c                |   59 ++++++++++---
 3 files changed, 145 insertions(+), 14 deletions(-)

diff --git a/src/tracker-indexer/tracker-dbus.c b/src/tracker-indexer/tracker-dbus.c
index 932fb24..f2392ae 100644
--- a/src/tracker-indexer/tracker-dbus.c
+++ b/src/tracker-indexer/tracker-dbus.c
@@ -31,6 +31,13 @@
 
 static DBusGConnection *connection;
 static DBusGProxy      *gproxy;
+static GHashTable      *name_monitors;
+
+typedef struct {
+	TrackerDBusNameMonitorFunc func;
+	gpointer user_data;
+	GDestroyNotify destroy_func;
+} TrackerDBusNameMonitor;
 
 static gboolean
 dbus_register_service (DBusGProxy  *proxy,
@@ -47,7 +54,7 @@ dbus_register_service (DBusGProxy  *proxy,
 						name,
 						DBUS_NAME_FLAG_DO_NOT_QUEUE,
 						&result, &error)) {
-		g_critical ("Could not aquire name:'%s', %s",
+		g_critical ("Could not acquire name:'%s', %s",
 			    name,
 			    error ? error->message : "no error given");
 		g_error_free (error);
@@ -72,12 +79,23 @@ name_owner_changed_cb (DBusGProxy *proxy,
 		       gchar	  *new_owner,
 		       gpointer    user_data)
 {
+	TrackerDBusNameMonitor *name_monitor;
+
 	if (strcmp (name, TRACKER_DAEMON_SERVICE) == 0 && (!new_owner || !*new_owner)) {
 		/* Tracker daemon has dissapeared from
 		 * the bus, shutdown the indexer.
 		 */
 		tracker_indexer_stop (TRACKER_INDEXER (user_data));
 	}
+
+	name_monitor = g_hash_table_lookup (name_monitors, name);
+
+	if (name_monitor) {
+		gboolean available;
+
+		available = (new_owner && *new_owner);
+		(name_monitor->func) (name, available, name_monitor->user_data);
+	}
 }
 
 static gboolean
@@ -144,6 +162,31 @@ dbus_register_names (void)
 	return TRUE;
 }
 
+static TrackerDBusNameMonitor *
+name_monitor_new (TrackerDBusNameMonitorFunc func,
+		  gpointer                   user_data,
+		  GDestroyNotify             destroy_func)
+{
+	TrackerDBusNameMonitor *name_monitor;
+
+	name_monitor = g_slice_new (TrackerDBusNameMonitor);
+	name_monitor->func = func;
+	name_monitor->user_data = user_data;
+	name_monitor->destroy_func = destroy_func;
+
+	return name_monitor;
+}
+
+static void
+name_monitor_free (TrackerDBusNameMonitor *name_monitor)
+{
+	if (name_monitor->user_data && name_monitor->destroy_func) {
+		(name_monitor->destroy_func) (name_monitor->user_data);
+	}
+
+	g_slice_free (TrackerDBusNameMonitor, name_monitor);
+}
+
 gboolean
 tracker_dbus_init (void)
 {
@@ -157,6 +200,10 @@ tracker_dbus_init (void)
 		return FALSE;
 	}
 
+	name_monitors = g_hash_table_new_full (g_str_hash,
+					       g_str_equal,
+					       (GDestroyNotify) g_free,
+					       (GDestroyNotify) name_monitor_free);
 	return TRUE;
 }
 
@@ -169,6 +216,9 @@ tracker_dbus_shutdown (void)
 	}
 
 	connection = NULL;
+
+	g_hash_table_destroy (name_monitors);
+	name_monitors = NULL;
 }
 
 gboolean
@@ -191,3 +241,40 @@ tracker_dbus_register_object (GObject *object)
 
 	return FALSE;
 }
+
+void
+tracker_dbus_add_name_monitor (const gchar                *name,
+			       TrackerDBusNameMonitorFunc  func,
+			       gpointer                    user_data,
+			       GDestroyNotify              destroy_func)
+{
+	g_return_if_fail (name != NULL);
+	g_return_if_fail (func != NULL);
+
+	if (!name_monitors) {
+		g_critical ("DBus support must be initialized before adding name monitors!");
+		return;
+	}
+
+	if (g_hash_table_lookup (name_monitors, name) != NULL) {
+		g_critical ("There is already a name monitor for such name");
+		return;
+	}
+
+	g_hash_table_insert (name_monitors,
+			     g_strdup (name),
+			     name_monitor_new (func, user_data, destroy_func));
+}
+
+void
+tracker_dbus_remove_name_monitor (const gchar *name)
+{
+	g_return_if_fail (name != NULL);
+
+	if (!name_monitors) {
+		g_critical ("DBus support must be initialized before removing name monitors!");
+		return;
+	}
+
+	g_hash_table_remove (name_monitors, name);
+}
diff --git a/src/tracker-indexer/tracker-dbus.h b/src/tracker-indexer/tracker-dbus.h
index 603957f..0a8fa65 100644
--- a/src/tracker-indexer/tracker-dbus.h
+++ b/src/tracker-indexer/tracker-dbus.h
@@ -28,10 +28,19 @@
 
 G_BEGIN_DECLS
 
+typedef void (* TrackerDBusNameMonitorFunc) (const gchar *name,
+					     gboolean     available,
+					     gpointer     user_data);
+
 gboolean    tracker_dbus_init		   (void);
 void	    tracker_dbus_shutdown	   (void);
 gboolean    tracker_dbus_register_object   (GObject *object);
-DBusGProxy *tracker_dbus_extract_get_proxy (void);
+
+void        tracker_dbus_add_name_monitor     (const gchar                *name,
+					       TrackerDBusNameMonitorFunc  func,
+					       gpointer                    user_data,
+					       GDestroyNotify              destroy_func);
+void        tracker_dbus_remove_name_monitor  (const gchar                *name);
 
 G_END_DECLS
 
diff --git a/src/tracker-indexer/tracker-module-metadata-utils.c b/src/tracker-indexer/tracker-module-metadata-utils.c
index b830efd..afaf2e2 100644
--- a/src/tracker-indexer/tracker-module-metadata-utils.c
+++ b/src/tracker-indexer/tracker-module-metadata-utils.c
@@ -73,6 +73,45 @@ typedef struct {
         GPid pid;
 } ExtractorContext;
 
+static GPid extractor_pid = 0;
+
+
+static DBusGProxy * get_dbus_extract_proxy (void);
+
+static GPid
+get_extractor_pid (void)
+{
+	GError *error;
+	GPid pid;
+
+	/* Get new PID from extractor */
+	if (!org_freedesktop_Tracker_Extract_get_pid (get_dbus_extract_proxy (),
+						      &pid,
+						      &error)) {
+		g_critical ("Couldn't get PID from tracker-extract, %s",
+			    error ? error->message : "no error given");
+		g_clear_error (&error);
+		pid = 0;
+	}
+
+	g_message ("New extractor PID is %d", (guint) pid);
+
+	return pid;
+}
+
+static void
+extractor_changed_availability_cb (const gchar *name,
+				   gboolean     available,
+				   gpointer     user_data)
+{
+	if (!available) {
+		/* invalidate PID */
+		extractor_pid = 0;
+	} else {
+		extractor_pid = get_extractor_pid ();
+	}
+}
+
 static DBusGProxy *
 get_dbus_extract_proxy (void)
 {
@@ -104,6 +143,9 @@ get_dbus_extract_proxy (void)
                 g_critical ("Could not create a DBusGProxy to the extract service");
         }
 
+	tracker_dbus_add_name_monitor ("org.freedesktop.Tracker.Extract",
+				       extractor_changed_availability_cb,
+				       NULL, NULL);
         return proxy;
 }
 
@@ -221,23 +263,16 @@ static ExtractorContext *
 extractor_context_create (TrackerModuleMetadata *metadata)
 {
         ExtractorContext *context;
-        GError *error = NULL;
-        pid_t pid;
 
-        /* Call extractor to get PID so we can kill it if anything goes wrong. */
-        if (!org_freedesktop_Tracker_Extract_get_pid (get_dbus_extract_proxy (),
-                                                      &pid,
-                                                      &error)) {
-                g_critical ("Couldn't get PID from tracker-extract, %s",
-			    error ? error->message : "no error given");
-                g_clear_error (&error);
-                return NULL;
-        }
+	if (G_UNLIKELY (extractor_pid == 0)) {
+		/* Ensure we have a PID to kill if anything goes wrong */
+		extractor_pid = get_extractor_pid ();
+	}
 
         context = g_slice_new0 (ExtractorContext);
         context->main_loop = g_main_loop_new (NULL, FALSE);
         context->metadata = g_object_ref (metadata);
-        context->pid = pid;
+        context->pid = extractor_pid;
 
         return context;
 }



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