[tracker/gdbus-porting] Porting GetMetadataFast clientside call to GDBus - WIP



commit a22b97dbebda20101409334d03c8db0c870f9659
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      |   20 ++++--
 src/libtracker-common/tracker-dbus.c |  125 +++++++++++++++++++--------------
 src/libtracker-common/tracker-dbus.h |    6 +-
 src/miners/fs/tracker-miner-files.c  |  113 +++++++++++++------------------
 4 files changed, 136 insertions(+), 128 deletions(-)
---
diff --git a/src/libtracker-client/tracker.c b/src/libtracker-client/tracker.c
index da821cc..071211b 100644
--- a/src/libtracker-client/tracker.c
+++ b/src/libtracker-client/tracker.c
@@ -610,6 +610,7 @@ iterator_buffer_read_int (TrackerResultIterator *iterator)
 	return v;
 }
 
+#if 0
 static void
 callback_iterator (void     *buffer,
                    gssize    buffer_size,
@@ -660,6 +661,7 @@ callback_iterator (void     *buffer,
 
 	fast_async_data_free (fad);
 }
+#endif
 
 /* Deprecated and only used for 0.6 API */
 static void
@@ -1742,6 +1744,7 @@ tracker_resources_sparql_query_iterate (TrackerClient  *client,
 
 	iterator = g_slice_new0 (TrackerResultIterator);
 
+	// todo remove
 	tracker_dbus_send_and_splice (connection,
 	                              message,
 	                              pipefd[0],
@@ -2221,13 +2224,16 @@ tracker_resources_sparql_query_iterate_async (TrackerClient         *client,
 	                           user_data);
 	fad->iterator_callback = callback;
 
-	tracker_dbus_send_and_splice_async (connection,
-	                                    message,
-	                                    pipefd[0],
-	                                    TRUE,
-	                                    cancellable,
-	                                    callback_iterator,
-	                                    fad);
+	// todo: port to gdbus or remove this function
+	g_critical ("Unsupported call, not ported to GDBus");
+
+//	tracker_dbus_send_and_splice_async (connection,
+//	                                    message,
+//	                                    pipefd[0],
+//	                                    TRUE,
+//	                                    cancellable,
+//	                                    callback_iterator,
+//	                                    fad);
 
 	return fad->request_id;
 }
diff --git a/src/libtracker-common/tracker-dbus.c b/src/libtracker-common/tracker-dbus.c
index 664f0d0..b1d4d9f 100644
--- a/src/libtracker-common/tracker-dbus.c
+++ b/src/libtracker-common/tracker-dbus.c
@@ -45,10 +45,10 @@ 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;
 
 static gboolean client_lookup_enabled;
@@ -626,9 +626,10 @@ tracker_dbus_enable_client_lookup (gboolean enabled)
 	client_lookup_enabled = enabled;
 }
 
+// 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;
@@ -657,6 +658,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,
@@ -765,8 +768,7 @@ static SendAndSpliceData *
 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)
 {
@@ -776,10 +778,11 @@ 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;
 
 	return data;
 }
@@ -790,7 +793,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);
 }
 
@@ -800,7 +808,6 @@ send_and_splice_async_callback (GObject      *source,
                                 gpointer      user_data)
 {
 	SendAndSpliceData *data = user_data;
-	DBusMessage *reply = NULL;
 	GError *error = NULL;
 
 	g_output_stream_splice_finish (data->output_stream,
@@ -808,21 +815,15 @@ send_and_splice_async_callback (GObject      *source,
 	                               &error);
 
 	if (G_LIKELY (!error)) {
-		dbus_pending_call_block (data->call);
-		reply = dbus_pending_call_steal_reply (data->call);
+		/* 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_UNLIKELY (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
@@ -832,11 +833,7 @@ send_and_splice_async_callback (GObject      *source,
 		} else {
 			GStrv v_names = NULL;
 
-			if (data->expect_variable_names) {
-				v_names = dbus_send_and_splice_get_variable_names (reply, FALSE);
-			}
-
-			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)),
@@ -860,44 +857,65 @@ send_and_splice_async_callback (GObject      *source,
 		 * callback itself. */
 	}
 
-	if (reply) {
-		dbus_message_unref (reply);
+	send_and_splice_data_free (data);
+}
+
+static void
+tracker_dbus_send_and_splice_async_finish (GObject      *source,
+                                           GAsyncResult *result,
+                                           gpointer      user_data)
+{
+	SendAndSpliceData *data = user_data;
+	GError *error = NULL;
+
+	data->reply = g_dbus_connection_send_message_with_reply_finish ((GDBusConnection *) source,
+	                                                                result, &error);
+
+	if (error) {
+		g_critical ("FD passing unsupported or connection disconnected: %s",
+		            error ? error->message : "No error provided");
+		g_error_free (error);
+		return;
 	}
 
-	send_and_splice_data_free (data);
+	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,
+	                              data->cancellable,
+	                              send_and_splice_async_callback,
+	                              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);
@@ -906,19 +924,20 @@ tracker_dbus_send_and_splice_async (DBusConnection                   *connection
 	data = send_and_splice_data_new (unix_input_stream,
 	                                 buffered_input_stream,
 	                                 output_stream,
-	                                 expect_variable_names,
-	                                 call,
+	                                 cancellable,
 	                                 callback,
 	                                 user_data);
 
-	g_output_stream_splice_async (output_stream,
-	                              buffered_input_stream,
-	                              G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
-	                              G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
-	                              0,
-	                              cancellable,
-	                              send_and_splice_async_callback,
-	                              data);
+	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));
 
 	return TRUE;
 }
diff --git a/src/libtracker-common/tracker-dbus.h b/src/libtracker-common/tracker-dbus.h
index 5bbe55d..f3bc350 100644
--- a/src/libtracker-common/tracker-dbus.h
+++ b/src/libtracker-common/tracker-dbus.h
@@ -197,6 +197,7 @@ void             tracker_dbus_enable_client_lookup   (gboolean
 
 #ifndef NO_LIBDBUS
 /* 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,
@@ -206,10 +207,9 @@ 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,
                                                       TrackerDBusSendAndSpliceCallback callback,
                                                       gpointer                    user_data);
diff --git a/src/miners/fs/tracker-miner-files.c b/src/miners/fs/tracker-miner-files.c
index f7e6f3a..a184fc5 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,24 +2026,36 @@ 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);
 
 	tracker_dbus_send_and_splice_async (connection,
 	                                    message,
 	                                    pipefd[0],
-	                                    FALSE,
 	                                    cancellable,
 	                                    get_metadata_fast_cb,
 	                                    data);
@@ -2082,13 +2066,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]