[tracker/extractor-dbus-fd: 1/2] tracker-extract: Add a GetMetadataFast method
- From: Adrien Bustany <abustany src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/extractor-dbus-fd: 1/2] tracker-extract: Add a GetMetadataFast method
- Date: Wed, 30 Jun 2010 16:11:33 +0000 (UTC)
commit 6e12c5e74c0b20532b4d387b34357c023e4efb0e
Author: Adrien Bustany <abustany gnome org>
Date: Wed Jun 30 12:16:19 2010 +0200
tracker-extract: Add a GetMetadataFast method
The GetMetadataFast method uses DBus FD passing to transfer the
resulting SPARQL query. The client passes a FD when calling the method,
and the resulting queries will be written to that FD.
src/tracker-extract/Makefile.am | 1 +
src/tracker-extract/tracker-dbus.c | 19 +++
src/tracker-extract/tracker-dbus.h | 5 +
src/tracker-extract/tracker-extract.c | 222 +++++++++++++++++++++++++++++++++
src/tracker-extract/tracker-extract.h | 6 +
src/tracker-extract/tracker-main.c | 5 +
6 files changed, 258 insertions(+), 0 deletions(-)
---
diff --git a/src/tracker-extract/Makefile.am b/src/tracker-extract/Makefile.am
index d512f08..ac02995 100644
--- a/src/tracker-extract/Makefile.am
+++ b/src/tracker-extract/Makefile.am
@@ -13,6 +13,7 @@ INCLUDES = \
-I$(top_builddir)/src/libtracker-client \
$(WARN_CFLAGS) \
$(GLIB2_CFLAGS) \
+ $(GIO_CFLAGS) \
$(GCOV_CFLAGS) \
$(GDKPIXBUF_CFLAGS) \
$(GMODULE_CFLAGS) \
diff --git a/src/tracker-extract/tracker-dbus.c b/src/tracker-extract/tracker-dbus.c
index 0270ad2..b2a0702 100644
--- a/src/tracker-extract/tracker-dbus.c
+++ b/src/tracker-extract/tracker-dbus.c
@@ -177,6 +177,25 @@ tracker_dbus_register_objects (gpointer object)
return TRUE;
}
+#ifdef HAVE_DBUS_FD_PASSING
+gboolean
+tracker_dbus_connection_add_filter (DBusHandleMessageFunction function,
+ void *user_data)
+{
+ if (!connection) {
+ g_critical ("D-Bus support must be initialized before adding connection filters!");
+ return FALSE;
+ }
+
+ dbus_connection_add_filter (dbus_g_connection_get_connection (connection),
+ function,
+ user_data,
+ NULL);
+
+ return TRUE;
+}
+#endif /* HAVE_DBUS_FD_PASSING */
+
GObject *
tracker_dbus_get_object (GType type)
{
diff --git a/src/tracker-extract/tracker-dbus.h b/src/tracker-extract/tracker-dbus.h
index 7ffd5cc..1b6ee6c 100644
--- a/src/tracker-extract/tracker-dbus.h
+++ b/src/tracker-extract/tracker-dbus.h
@@ -24,12 +24,17 @@
#include <glib.h>
#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus.h>
G_BEGIN_DECLS
gboolean tracker_dbus_init (void);
void tracker_dbus_shutdown (void);
gboolean tracker_dbus_register_objects (gpointer object);
+#ifdef HAVE_DBUS_FD_PASSING
+gboolean tracker_dbus_connection_add_filter (DBusHandleMessageFunction function,
+ void *user_data);
+#endif /* HAVE_DBUS_FD_PASSING */
GObject *tracker_dbus_get_object (GType type);
G_END_DECLS
diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c
index ab9c8a9..f5d87eb 100644
--- a/src/tracker-extract/tracker-extract.c
+++ b/src/tracker-extract/tracker-extract.c
@@ -25,6 +25,9 @@
#include <gmodule.h>
#include <gio/gio.h>
+#include <gio/gunixoutputstream.h>
+#include <gio/gunixinputstream.h>
+
#include <libtracker-common/tracker-dbus.h>
#include <libtracker-common/tracker-log.h>
@@ -45,6 +48,9 @@
#define MAX_EXTRACT_TIME 10
+#define UNKNOWN_METHOD_MESSAGE "Method \"%s\" with signature \"%s\" on " \
+ "interface \"%s\" doesn't exist, expected \"%s\""
+
#define TRACKER_EXTRACT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_EXTRACT, TrackerExtractPrivate))
extern gboolean debug;
@@ -615,3 +621,219 @@ tracker_extract_get_metadata (TrackerExtract *object,
alarm (0);
}
}
+
+#ifdef HAVE_DBUS_FD_PASSING
+static void
+get_metadata_fast (TrackerExtract *object,
+ DBusConnection *connection,
+ DBusMessage *message)
+{
+ guint request_id;
+ const gchar *expected_signature;
+ TrackerExtractPrivate *priv;
+ DBusError dbus_error;
+ DBusMessage *reply;
+ const gchar *uri, *mime;
+ int fd;
+ GOutputStream *unix_output_stream;
+ GOutputStream *buffered_output_stream;
+ GDataOutputStream *data_output_stream;
+ GError *error = NULL;
+ TrackerSparqlBuilder *sparql, *preupdate;
+ gboolean extracted = FALSE;
+
+ request_id = tracker_dbus_get_next_request_id ();
+
+ expected_signature = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UNIX_FD_AS_STRING;
+
+ if (g_strcmp0 (dbus_message_get_signature (message), expected_signature)) {
+ gchar *error_message = g_strdup_printf (UNKNOWN_METHOD_MESSAGE,
+ "GetMetadataFast",
+ dbus_message_get_signature (message),
+ dbus_message_get_interface (message),
+ expected_signature);
+ tracker_dbus_request_new (request_id,
+ NULL,
+ "%s()",
+ __FUNCTION__);
+
+ reply = dbus_message_new_error (message,
+ DBUS_ERROR_UNKNOWN_METHOD,
+ error_message);
+ dbus_connection_send (connection, reply, NULL);
+
+ tracker_dbus_request_failed (request_id,
+ NULL,
+ NULL,
+ error_message);
+
+ dbus_message_unref (reply);
+ g_free (error_message);
+
+ return;
+ }
+
+ dbus_error_init (&dbus_error);
+
+ dbus_message_get_args (message,
+ &dbus_error,
+ DBUS_TYPE_STRING, &uri,
+ DBUS_TYPE_STRING, &mime,
+ DBUS_TYPE_UNIX_FD, &fd,
+ DBUS_TYPE_INVALID);
+
+ if (dbus_error_is_set (&dbus_error)) {
+ tracker_dbus_request_new (request_id,
+ NULL,
+ "%s()",
+ __FUNCTION__);
+
+ reply = dbus_message_new_error (message, dbus_error.name, dbus_error.message);
+ dbus_connection_send (connection, reply, NULL);
+
+ tracker_dbus_request_failed (request_id,
+ NULL,
+ NULL,
+ dbus_error.message);
+
+ dbus_message_unref (reply);
+ dbus_error_free (&dbus_error);
+
+ return;
+ }
+
+ tracker_dbus_request_new (request_id,
+ NULL,
+ "%s(uri:'%s', mime:%s)",
+ __FUNCTION__,
+ uri,
+ mime);
+
+ tracker_dbus_request_debug (request_id,
+ NULL,
+ " Resetting shutdown timeout");
+
+ priv = TRACKER_EXTRACT_GET_PRIVATE (object);
+
+ tracker_main_quit_timeout_reset ();
+ if (!priv->disable_shutdown) {
+ alarm (MAX_EXTRACT_TIME);
+ }
+
+ extracted = get_file_metadata (object, request_id, NULL, uri, mime, &preupdate, &sparql);
+
+ if (extracted) {
+ unix_output_stream = g_unix_output_stream_new (fd, TRUE);
+ buffered_output_stream = g_buffered_output_stream_new_sized (unix_output_stream,
+ 64*1024);
+ data_output_stream = g_data_output_stream_new (buffered_output_stream);
+ g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (data_output_stream),
+ G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN);
+
+ if (tracker_sparql_builder_get_length (sparql) > 0) {
+ const gchar *preupdate_str = NULL;
+
+ if (tracker_sparql_builder_get_length (preupdate) > 0) {
+ preupdate_str = tracker_sparql_builder_get_result (preupdate);
+ }
+
+ g_data_output_stream_put_string (data_output_stream,
+ preupdate_str ? preupdate_str : "",
+ NULL,
+ &error);
+
+ if (!error) {
+ g_data_output_stream_put_byte (data_output_stream,
+ 0,
+ NULL,
+ &error);
+ }
+
+ if (!error) {
+ g_data_output_stream_put_string (data_output_stream,
+ tracker_sparql_builder_get_result (sparql),
+ NULL,
+ &error);
+ }
+
+ if (!error) {
+ g_data_output_stream_put_byte (data_output_stream,
+ 0,
+ NULL,
+ &error);
+ }
+ }
+
+ g_object_unref (sparql);
+ g_object_unref (preupdate);
+ g_object_unref (data_output_stream);
+ g_object_unref (buffered_output_stream);
+ g_object_unref (unix_output_stream);
+
+ if (error) {
+ tracker_dbus_request_failed (request_id,
+ NULL,
+ &error,
+ NULL);
+ reply = dbus_message_new_error (message,
+ TRACKER_EXTRACT_SERVICE ".GetMetadataFastError",
+ error->message);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+ g_error_free (error);
+ } else {
+ tracker_dbus_request_success (request_id, NULL);
+ reply = dbus_message_new_method_return (message);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+ }
+ } else {
+ gchar *error_message = g_strdup_printf ("Could not get any metadata for uri:'%s' and mime:'%s'", uri, mime);
+ tracker_dbus_request_failed (request_id,
+ NULL,
+ NULL,
+ error_message);
+ reply = dbus_message_new_error (message,
+ TRACKER_EXTRACT_SERVICE ".GetMetadataFastError",
+ error_message);
+ close (fd);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+ g_free (error_message);
+ }
+
+ if (!priv->disable_shutdown) {
+ /* Unset alarm so the extractor doesn't die when it's idle */
+ alarm (0);
+ }
+}
+
+DBusHandlerResult
+tracker_extract_connection_filter (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ TrackerExtract *extract;
+
+ g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+ g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+ extract = user_data;
+ g_return_val_if_fail (TRACKER_IS_EXTRACT (extract), DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+ if (g_strcmp0 (TRACKER_EXTRACT_PATH, dbus_message_get_path (message))) {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ if (g_strcmp0 (TRACKER_EXTRACT_INTERFACE, dbus_message_get_interface (message))) {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ if (!g_strcmp0 ("GetMetadataFast", dbus_message_get_member (message))) {
+ get_metadata_fast (extract, connection, message);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+#endif /* HAVE_DBUS_FD_PASSING */
diff --git a/src/tracker-extract/tracker-extract.h b/src/tracker-extract/tracker-extract.h
index 25bd889..2542a41 100644
--- a/src/tracker-extract/tracker-extract.h
+++ b/src/tracker-extract/tracker-extract.h
@@ -23,6 +23,7 @@
#include <glib-object.h>
#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus.h>
#define TRACKER_EXTRACT_SERVICE "org.freedesktop.Tracker1.Extract"
#define TRACKER_EXTRACT_PATH "/org/freedesktop/Tracker1/Extract"
@@ -60,6 +61,11 @@ void tracker_extract_get_metadata (TrackerExtract
const gchar *mime,
DBusGMethodInvocation *context,
GError **error);
+#ifdef HAVE_DBUS_FD_PASSING
+DBusHandlerResult tracker_extract_connection_filter (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+#endif /* HAVE_DBUS_FD_PASSING */
/* Not DBus API */
void tracker_extract_get_metadata_by_cmdline (TrackerExtract *object,
diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c
index 394cd7f..2640931 100644
--- a/src/tracker-extract/tracker-main.c
+++ b/src/tracker-extract/tracker-main.c
@@ -453,6 +453,11 @@ main (int argc, char *argv[])
return EXIT_FAILURE;
}
+#ifdef HAVE_DBUS_FD_PASSING
+ tracker_dbus_connection_add_filter (tracker_extract_connection_filter,
+ object);
+#endif
+
g_message ("Waiting for D-Bus requests...");
tracker_albumart_init ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]