[tracker/gdbus: 37/74] Porting GetMetadataFast clientside call to GDBus - WIP



commit 3a9797840c395959214a3aa503753c1bf0d92650
Author: Philip Van Hoof <philip codeminded be>
Date:   Wed Jan 5 11:09:59 2011 +0100

    Porting GetMetadataFast clientside call to GDBus - WIP

 src/libtracker-client/tracker.c      |    1 +
 src/libtracker-common/tracker-dbus.c |  115 +++++++++++++++++++++-------------
 src/libtracker-common/tracker-dbus.h |    5 +-
 src/miners/fs/tracker-miner-files.c  |  112 ++++++++++++++-------------------
 4 files changed, 123 insertions(+), 110 deletions(-)
---
diff --git a/src/libtracker-client/tracker.c b/src/libtracker-client/tracker.c
index da821cc..c3154eb 100644
--- a/src/libtracker-client/tracker.c
+++ b/src/libtracker-client/tracker.c
@@ -1742,6 +1742,7 @@ tracker_resources_sparql_query_iterate (TrackerClient  *client,
 
 	iterator = g_slice_new0 (TrackerResultIterator);
 
+	// todo remove
 	tracker_dbus_send_and_splice (connection,
 	                              message,
 	                              pipefd[0],
diff --git a/src/libtracker-common/tracker-dbus.c b/src/libtracker-common/tracker-dbus.c
index 6b90990..6e36034 100644
--- a/src/libtracker-common/tracker-dbus.c
+++ b/src/libtracker-common/tracker-dbus.c
@@ -50,8 +50,9 @@ typedef struct {
 	GInputStream *unix_input_stream;
 	GInputStream *buffered_input_stream;
 	GOutputStream *output_stream;
-	DBusPendingCall *call;
+	GDBusMessage *reply;
 	TrackerDBusSendAndSpliceCallback callback;
+	GCancellable *cancellable;
 	gpointer user_data;
 	gboolean expect_variable_names;
 } SendAndSpliceData;
@@ -464,9 +465,10 @@ tracker_dbus_g_request_begin (DBusGMethodInvocation *context,
 	return request;
 }
 
+// todo remove
 static GStrv
-dbus_send_and_splice_get_variable_names (DBusMessage *message,
-                                         gboolean     copy_strings)
+dbus_send_and_splice_get_variable_names (DBusMessage  *message,
+                                         gboolean      copy_strings)
 {
 	GPtrArray *found;
 	DBusMessageIter iter, arr;
@@ -495,6 +497,8 @@ dbus_send_and_splice_get_variable_names (DBusMessage *message,
  * message with a refcount of 1 (and say goodbye to it, 'cause you'll never
  * see it again
  */
+
+// todo remove
 gboolean
 tracker_dbus_send_and_splice (DBusConnection  *connection,
                               DBusMessage     *message,
@@ -604,7 +608,7 @@ send_and_splice_data_new (GInputStream                     *unix_input_stream,
                           GInputStream                     *buffered_input_stream,
                           GOutputStream                    *output_stream,
                           gboolean                          expect_variable_names,
-                          DBusPendingCall                  *call,
+                          GCancellable                     *cancellable,
                           TrackerDBusSendAndSpliceCallback  callback,
                           gpointer                          user_data)
 {
@@ -614,7 +618,9 @@ send_and_splice_data_new (GInputStream                     *unix_input_stream,
 	data->unix_input_stream = unix_input_stream;
 	data->buffered_input_stream = buffered_input_stream;
 	data->output_stream = output_stream;
-	data->call = call;
+	if (cancellable) {
+		data->cancellable = g_object_ref (cancellable);
+	}
 	data->callback = callback;
 	data->user_data = user_data;
 	data->expect_variable_names = expect_variable_names;
@@ -628,7 +634,12 @@ send_and_splice_data_free (SendAndSpliceData *data)
 	g_object_unref (data->unix_input_stream);
 	g_object_unref (data->buffered_input_stream);
 	g_object_unref (data->output_stream);
-	dbus_pending_call_unref (data->call);
+	if (data->cancellable) {
+		g_object_unref (data->cancellable);
+	}
+	if (data->reply) {
+		g_object_unref (data->reply);
+	}
 	g_slice_free (SendAndSpliceData, data);
 }
 
@@ -637,30 +648,38 @@ send_and_splice_async_callback (GObject      *source,
                                 GAsyncResult *result,
                                 gpointer      user_data)
 {
+	GError *error = NULL;
+
+	g_output_stream_splice_finish (G_OUTPUT_STREAM (source), result, &error);
+
+	if (error) {
+		g_critical ("Error while splicing: %s",
+		            error ? error->message : "Error not specified");
+		g_error_free (error);
+	}
+}
+
+static void
+tracker_dbus_send_and_splice_async_finish (GObject      *source,
+                                           GAsyncResult *result,
+                                           gpointer      user_data)
+{
 	SendAndSpliceData *data = user_data;
-	DBusMessage *reply = NULL;
 	GError *error = NULL;
 
-	g_output_stream_splice_finish (data->output_stream,
-	                               result,
-	                               &error);
+	data->reply = g_dbus_connection_send_message_with_reply_finish (G_DBUS_CONNECTION (source),
+	                                                                result, &error);
 
-	if (G_LIKELY (!error)) {
-		dbus_pending_call_block (data->call);
-		reply = dbus_pending_call_steal_reply (data->call);
+	if (!error) {
+		/* dbus_pending_call_block (data->call);
+		   reply = dbus_pending_call_steal_reply (data->call); */
 
-		if (G_UNLIKELY (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)) {
-			DBusError dbus_error;
+		if (g_dbus_message_get_message_type (data->reply) == G_DBUS_MESSAGE_TYPE_ERROR) {
 
 			/* If any error happened, we're not passing any received data, so we
 			 * need to free it */
 			g_free (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->output_stream)));
 
-			dbus_error_init (&dbus_error);
-			dbus_set_error_from_message (&dbus_error, reply);
-			dbus_set_g_error (&error, &dbus_error);
-			dbus_error_free (&dbus_error);
-
 			(* data->callback) (NULL, -1, NULL, error, data->user_data);
 
 			/* Note: GError should be freed by callback. We do this to be aligned
@@ -671,10 +690,13 @@ send_and_splice_async_callback (GObject      *source,
 			GStrv v_names = NULL;
 
 			if (data->expect_variable_names) {
+#if 0
+				todo: port this function
 				v_names = dbus_send_and_splice_get_variable_names (reply, FALSE);
+#endif
 			}
 
-			dbus_pending_call_cancel (data->call);
+			/* dbus_pending_call_cancel (data->call); */
 
 			(* data->callback) (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->output_stream)),
 			                    g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->output_stream)),
@@ -698,44 +720,38 @@ send_and_splice_async_callback (GObject      *source,
 		 * callback itself. */
 	}
 
-	if (reply) {
-		dbus_message_unref (reply);
-	}
-
 	send_and_splice_data_free (data);
 }
 
+static void
+tracker_g_async_ready_callback (GObject      *source_object,
+                                GAsyncResult *res,
+                                gpointer      user_data)
+{
+	g_simple_async_result_set_op_res_gpointer (user_data, g_object_ref (res), g_object_unref);
+	g_simple_async_result_complete (user_data);
+	g_object_unref (user_data);
+}
+
 gboolean
-tracker_dbus_send_and_splice_async (DBusConnection                   *connection,
-                                    DBusMessage                      *message,
+tracker_dbus_send_and_splice_async (GDBusConnection                  *connection,
+                                    GDBusMessage                     *message,
                                     int                               fd,
                                     gboolean                          expect_variable_names,
                                     GCancellable                     *cancellable,
                                     TrackerDBusSendAndSpliceCallback  callback,
                                     gpointer                          user_data)
 {
-	DBusPendingCall *call;
+	SendAndSpliceData *data;
 	GInputStream *unix_input_stream;
 	GInputStream *buffered_input_stream;
 	GOutputStream *output_stream;
-	SendAndSpliceData *data;
 
 	g_return_val_if_fail (connection != NULL, FALSE);
 	g_return_val_if_fail (message != NULL, FALSE);
 	g_return_val_if_fail (fd > 0, FALSE);
 	g_return_val_if_fail (callback != NULL, FALSE);
 
-	dbus_connection_send_with_reply (connection,
-	                                 message,
-	                                 &call,
-	                                 -1);
-	dbus_message_unref (message);
-
-	if (!call) {
-		g_critical ("FD passing unsupported or connection disconnected");
-		return FALSE;
-	}
-
 	unix_input_stream = g_unix_input_stream_new (fd, TRUE);
 	buffered_input_stream = g_buffered_input_stream_new_sized (unix_input_stream,
 	                                                           TRACKER_DBUS_PIPE_BUFFER_SIZE);
@@ -745,16 +761,27 @@ tracker_dbus_send_and_splice_async (DBusConnection                   *connection
 	                                 buffered_input_stream,
 	                                 output_stream,
 	                                 expect_variable_names,
-	                                 call,
+	                                 cancellable,
 	                                 callback,
 	                                 user_data);
 
-	g_output_stream_splice_async (output_stream,
-	                              buffered_input_stream,
+	g_dbus_connection_send_message_with_reply (connection,
+	                                           message,
+	                                           G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+	                                           -1,
+	                                           NULL,
+	                                           cancellable,
+	                                           tracker_g_async_ready_callback,
+	                                           g_simple_async_result_new (G_OBJECT (connection),
+	                                                                      tracker_dbus_send_and_splice_async_finish,
+	                                                                      user_data, NULL));
+
+	g_output_stream_splice_async (data->output_stream,
+	                              data->buffered_input_stream,
 	                              G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
 	                              G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
 	                              0,
-	                              cancellable,
+	                              data->cancellable,
 	                              send_and_splice_async_callback,
 	                              data);
 
diff --git a/src/libtracker-common/tracker-dbus.h b/src/libtracker-common/tracker-dbus.h
index 9e58bc1..74c5f6e 100644
--- a/src/libtracker-common/tracker-dbus.h
+++ b/src/libtracker-common/tracker-dbus.h
@@ -172,6 +172,7 @@ TrackerDBusRequest *tracker_dbus_g_request_begin       (DBusGMethodInvocation
                                                         ...);
 
 /* File descriptor convenience API */
+// todo: remove this api, only used by libtracker-client
 gboolean            tracker_dbus_send_and_splice       (DBusConnection             *connection,
                                                         DBusMessage                *message,
                                                         int                         fd,
@@ -181,8 +182,8 @@ gboolean            tracker_dbus_send_and_splice       (DBusConnection
                                                         GStrv                      *variable_names,
                                                         GError                    **error);
 
-gboolean            tracker_dbus_send_and_splice_async (DBusConnection             *connection,
-                                                        DBusMessage                *message,
+gboolean            tracker_dbus_send_and_splice_async (GDBusConnection            *connection,
+                                                        GDBusMessage               *message,
                                                         int                         fd,
                                                         gboolean                    expect_variable_names,
                                                         GCancellable               *cancellable,
diff --git a/src/miners/fs/tracker-miner-files.c b/src/miners/fs/tracker-miner-files.c
index f7e6f3a..78265e2 100644
--- a/src/miners/fs/tracker-miner-files.c
+++ b/src/miners/fs/tracker-miner-files.c
@@ -30,6 +30,8 @@
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
 
+#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
 #include <gio/gunixinputstream.h>
 
 #include <dbus/dbus-glib-lowlevel.h>
@@ -73,11 +75,15 @@ struct ProcessFileData {
 	TrackerSparqlBuilder *sparql;
 	GCancellable *cancellable;
 	GFile *file;
-	DBusPendingCall *call;
 };
 
+typedef void (*fast_async_cb) (gchar    *preupdate,
+                               gchar    *sparql,
+                               GError   *error,
+                               gpointer  user_data);
+
 typedef struct {
-	org_freedesktop_Tracker1_Extract_get_metadata_reply callback;
+	fast_async_cb callback;
 	gpointer user_data;
 } FastAsyncData;
 
@@ -100,8 +106,7 @@ struct TrackerMinerFilesPrivate {
 #endif /* defined(HAVE_UPOWER) || defined(HAVE_HAL) */
 	gulong finished_handler;
 
-	DBusGConnection *connection;
-	DBusGProxy *extractor_proxy;
+	GDBusConnection *connection;
 
 	GQuark quark_mount_point_uuid;
 	GQuark quark_directory_config_root;
@@ -176,7 +181,6 @@ static void        trigger_recheck_cb                   (GObject              *g
 static void        index_volumes_changed_cb             (GObject              *gobject,
 							 GParamSpec           *arg1,
 							 gpointer              user_data);
-static DBusGProxy *extractor_create_proxy               (DBusGConnection      *connection);
 static gboolean    miner_files_check_file               (TrackerMinerFS       *fs,
                                                          GFile                *file);
 static gboolean    miner_files_check_directory          (TrackerMinerFS       *fs,
@@ -294,7 +298,7 @@ tracker_miner_files_init (TrackerMinerFiles *mf)
 	                  mf);
 
 	/* Set up extractor and signals */
-	priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	priv->connection =  g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
 
 	if (!priv->connection) {
 		g_critical ("Could not connect to the D-Bus session bus, %s",
@@ -302,8 +306,6 @@ tracker_miner_files_init (TrackerMinerFiles *mf)
 		g_error_free (error);
 	}
 
-	priv->extractor_proxy = extractor_create_proxy (priv->connection);
-
 	priv->quark_mount_point_uuid = g_quark_from_static_string ("tracker-mount-point-uuid");
 	priv->quark_directory_config_root = g_quark_from_static_string ("tracker-directory-config-root");
 
@@ -359,8 +361,6 @@ miner_files_finalize (GObject *object)
 	mf = TRACKER_MINER_FILES (object);
 	priv = mf->private;
 
-	g_object_unref (priv->extractor_proxy);
-
 	g_signal_handlers_disconnect_by_func (priv->config,
 	                                      low_disk_space_limit_cb,
 	                                      NULL);
@@ -1842,42 +1842,11 @@ process_file_data_free (ProcessFileData *data)
 	g_slice_free (ProcessFileData, data);
 }
 
-static DBusGProxy *
-extractor_create_proxy (DBusGConnection *connection)
-{
-	DBusGProxy *proxy;
-
-	g_return_val_if_fail (connection, NULL);
-
-	/* Get proxy for the extractor */
-	proxy = dbus_g_proxy_new_for_name (connection,
-	                                   "org.freedesktop.Tracker1.Extract",
-	                                   "/org/freedesktop/Tracker1/Extract",
-	                                   "org.freedesktop.Tracker1.Extract");
-
-	if (!proxy) {
-		g_critical ("Could not create a DBusGProxy to the extract service");
-	} else {
-		/* Set default timeout for DBus requests to be around 60s.
-		 * Assuming that the files which need more time to get extracted are PDFs
-		 * using libpoppler, we already have a limit in the PDF extractor not to
-		 * spend more than 5s extraction contents. And, assuming the default
-		 * value of 10 in process-pool-limit, it means we may end up queueing up
-		 * to 10 PDF files which may need 5s each, so in order not to have dbus
-		 * timeouts in this case, any value greater than 5*10 would be good.
-		 */
-		dbus_g_proxy_set_default_timeout (proxy, EXTRACTOR_DBUS_TIMEOUT);
-	}
-
-	return proxy;
-}
-
 static void
-extractor_get_embedded_metadata_cb (DBusGProxy *proxy,
-                                    gchar      *preupdate,
-                                    gchar      *sparql,
-                                    GError     *error,
-                                    gpointer    user_data)
+extractor_get_embedded_metadata_cb (gchar    *preupdate,
+                                    gchar    *sparql,
+                                    GError   *error,
+                                    gpointer  user_data)
 {
 	ProcessFileData *data = user_data;
 	const gchar *uuid;
@@ -1919,7 +1888,7 @@ extractor_get_embedded_metadata_cb (DBusGProxy *proxy,
 	}
 
 	uuid = g_object_get_qdata (G_OBJECT (data->file),
-				  data->miner->private->quark_mount_point_uuid);
+	                           data->miner->private->quark_mount_point_uuid);
 
 	/* File represents a mount point */
 	if (G_UNLIKELY (uuid)) {
@@ -1977,7 +1946,7 @@ extractor_get_embedded_metadata_cancel (GCancellable    *cancellable,
 }
 
 static FastAsyncData*
-fast_async_data_new (org_freedesktop_Tracker1_Extract_get_metadata_reply callback,
+fast_async_data_new (fast_async_cb  callback,
                      gpointer       user_data)
 {
 	FastAsyncData *data;
@@ -2014,7 +1983,7 @@ get_metadata_fast_cb (void     *buffer,
 	if (G_UNLIKELY (error)) {
 		if (error->code != G_IO_ERROR_CANCELLED) {
 			/* ProcessFileData and error are freed in the callback */
-			(* data->callback) (NULL, NULL, NULL, error, process_data);
+			(* data->callback) (NULL, NULL, error, process_data);
 		} else {
 			/* Free error ourselves */
 			g_error_free (error);
@@ -2025,7 +1994,7 @@ get_metadata_fast_cb (void     *buffer,
 			sparql = preupdate + strlen (preupdate) + 1;
 		}
 
-		(* data->callback) (NULL, preupdate, sparql, NULL, data->user_data);
+		(* data->callback) (preupdate, sparql, NULL, data->user_data);
 		g_free (preupdate);
 	}
 
@@ -2033,16 +2002,19 @@ get_metadata_fast_cb (void     *buffer,
 }
 
 static void
-get_metadata_fast_async (DBusConnection  *connection,
+get_metadata_fast_async (GDBusConnection *connection,
                          const gchar     *uri,
                          const gchar     *mime_type,
                          GCancellable    *cancellable,
-                         org_freedesktop_Tracker1_Extract_get_metadata_reply callback,
+                         fast_async_cb    callback,
                          ProcessFileData *user_data)
 {
-	int pipefd[2];
-	DBusMessage *message;
+	GDBusMessage *message;
+	GVariant *arguments;
+	GVariantBuilder arguments_builder;
+	GUnixFDList *fd_list;
 	FastAsyncData *data;
+	int pipefd[2];
 
 	g_return_if_fail (connection);
 	g_return_if_fail (uri);
@@ -2054,17 +2026,30 @@ get_metadata_fast_async (DBusConnection  *connection,
 		return;
 	}
 
-	message = dbus_message_new_method_call (TRACKER_DBUS_SERVICE_EXTRACT,
-	                                        TRACKER_DBUS_PATH_EXTRACT,
-	                                        TRACKER_DBUS_INTERFACE_EXTRACT,
-	                                        "GetMetadataFast");
-	dbus_message_append_args (message,
-	                          DBUS_TYPE_STRING, &uri,
-	                          DBUS_TYPE_STRING, &mime_type,
-	                          DBUS_TYPE_UNIX_FD, &pipefd[1],
-	                          DBUS_TYPE_INVALID);
+	message = g_dbus_message_new_method_call (TRACKER_DBUS_SERVICE_EXTRACT,
+	                                          TRACKER_DBUS_PATH_EXTRACT,
+	                                          TRACKER_DBUS_INTERFACE_EXTRACT,
+	                                          "GetMetadataFast");
+
+	g_variant_builder_init (&arguments_builder, G_VARIANT_TYPE_TUPLE);
+
+	fd_list = g_unix_fd_list_new ();
+
+	g_variant_builder_add (&arguments_builder, "ssh",
+	                       uri,
+	                       mime_type,
+	                       g_unix_fd_list_append (fd_list,
+	                                              pipefd[1],
+	                                              NULL));
+
 	close (pipefd[1]);
 
+	arguments = g_variant_builder_end (&arguments_builder);
+	g_dbus_message_set_body (message, arguments);
+	g_dbus_message_set_unix_fd_list (message, fd_list);
+
+	g_object_unref (fd_list);
+
 	data = fast_async_data_new (callback,
 	                            user_data);
 
@@ -2082,13 +2067,12 @@ extractor_get_embedded_metadata (ProcessFileData *data,
                                  const gchar     *uri,
                                  const gchar     *mime_type)
 {
-	get_metadata_fast_async (dbus_g_connection_get_connection (data->miner->private->connection),
+	get_metadata_fast_async (data->miner->private->connection,
 	                         uri,
 	                         mime_type,
 	                         data->cancellable,
 	                         extractor_get_embedded_metadata_cb,
 	                         data);
-	data->call = NULL;
 
 	g_signal_connect (data->cancellable, "cancelled",
 	                  G_CALLBACK (extractor_get_embedded_metadata_cancel), data);



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