diff --git a/src/libtracker-common/Makefile.am b/src/libtracker-common/Makefile.am index e0fb4ae..b34a2f7 100644 --- a/src/libtracker-common/Makefile.am +++ b/src/libtracker-common/Makefile.am @@ -36,6 +36,7 @@ libtracker_common_la_SOURCES = \ $(hal_sources) \ tracker-config.c \ tracker-dbus.c \ + tracker-dbus-server.c \ tracker-field.c \ tracker-file-utils.c \ tracker-ioprio.c \ @@ -55,6 +56,7 @@ libtracker_common_la_SOURCES = \ noinst_HEADERS = \ $(hal_headers) \ tracker-dbus.h \ + tracker-dbus-server.h \ tracker-ioprio.h \ tracker-log.h \ tracker-nfs-lock.h \ diff --git a/src/libtracker-common/tracker-dbus-server.c b/src/libtracker-common/tracker-dbus-server.c new file mode 100644 index 0000000..99fef4a --- /dev/null +++ b/src/libtracker-common/tracker-dbus-server.c @@ -0,0 +1,341 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org) + * Copyright (C) 2008, Nokia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "tracker-dbus-server.h" +#include +#include + + +#define TRACKER_DBUS_SERVER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_DBUS_SERVER, TrackerDBusServerPrivate)) + +typedef struct TrackerDBusServerPrivate TrackerDBusServerPrivate; + +struct TrackerDBusServerPrivate { + DBusServer *server; + DBusConnection *connection; + DBusGConnection *gconnection; + gchar *address; + gchar *service_path; +}; + +enum { + PROP_0, + PROP_SERVICE_PATH, + PROP_HAS_CONNECTION +}; + + +static void tracker_dbus_server_finalize (GObject *object); +static void tracker_dbus_server_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void tracker_dbus_server_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + + +G_DEFINE_TYPE (TrackerDBusServer, tracker_dbus_server, G_TYPE_OBJECT) + + +static void +tracker_dbus_server_class_init (TrackerDBusServerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = tracker_dbus_server_finalize; + object_class->set_property = tracker_dbus_server_set_property; + object_class->get_property = tracker_dbus_server_get_property; + + g_object_class_install_property (object_class, + PROP_SERVICE_PATH, + g_param_spec_string ("service-path", + "Service path", + "Path to service executable", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_HAS_CONNECTION, + g_param_spec_string ("has-connection", + "Has connection", + "Whether the server has an established connection", + FALSE, + G_PARAM_READABLE)); + + g_type_class_add_private (object_class, sizeof (TrackerDBusServerPrivate)); +} + +static void +server_unregister_handler (DBusConnection *connection, + gpointer user_data) +{ + g_message ("Connection unregistered"); +} + +static DBusHandlerResult +server_message_handler (DBusConnection *connection, + DBusMessage *message, + gpointer user_data) +{ + TrackerDBusServer *server; + TrackerDBusServerPrivate *priv; + + server = TRACKER_DBUS_SERVER (user_data); + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (server); + + if (dbus_message_is_signal (message, + DBUS_INTERFACE_LOCAL, + "Disconnected")) { + if (priv->connection == connection) { + priv->gconnection = NULL; + + dbus_connection_unref (priv->connection); + priv->connection = NULL; + + g_object_notify (G_OBJECT (server), "has-connection"); + } + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void +server_connection_handler (DBusServer *bus_server, + DBusConnection *connection, + gpointer user_data) +{ + TrackerDBusServer *server; + TrackerDBusServerPrivate *priv; + DBusObjectPathVTable vtable = { &server_unregister_handler, + &server_message_handler }; + + server = TRACKER_DBUS_SERVER (user_data); + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (server); + + if (priv->connection) { + g_critical ("There's already an available connection"); + return; + } + + dbus_connection_register_fallback (connection, + "/org/freedesktop", + &vtable, user_data); + + dbus_connection_setup_with_g_main (connection, NULL); + + priv->connection = dbus_connection_ref (connection); + priv->gconnection = dbus_connection_get_g_connection (connection); +} + +static void +tracker_dbus_server_init (TrackerDBusServer *server) +{ + TrackerDBusServerPrivate *priv; + DBusError error; + + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (server); + + dbus_error_init (&error); + priv->server = dbus_server_listen ("unix:tmpdir=/tmp/tracker-address", &error); + + if (dbus_error_is_set (&error)) { + g_critical ("DBusServer could not be created: %s", error.message); + dbus_error_free (&error); + return; + } + + if (!priv->server) { + g_critical ("DBusServer could not be created"); + return; + } + + priv->address = dbus_server_get_address (priv->server); + g_message ("Created DBusServer in address: %s", priv->address); + + dbus_server_setup_with_g_main (priv->server, NULL); + dbus_server_set_new_connection_function (priv->server, + server_connection_handler, + server, NULL); +} + +static void +tracker_dbus_server_finalize (GObject *object) +{ + TrackerDBusServerPrivate *priv; + + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (object); + + if (priv->connection) { + dbus_connection_unref (priv->connection); + } + + if (priv->server) { + dbus_server_disconnect (priv->server); + dbus_server_unref (priv->server); + } + + g_free (priv->address); + g_free (priv->service_path); + + return G_OBJECT_CLASS (tracker_dbus_server_parent_class)->finalize (object); +} + +static void +tracker_dbus_server_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + TrackerDBusServerPrivate *priv; + + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_SERVICE_PATH: + priv->service_path = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +tracker_dbus_server_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + TrackerDBusServerPrivate *priv; + + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_SERVICE_PATH: + g_value_set_string (value, priv->service_path); + break; + case PROP_HAS_CONNECTION: + g_value_set_boolean (value, (priv->connection != NULL)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +TrackerDBusServer * +tracker_dbus_server_new (const gchar *service_path) +{ + g_return_val_if_fail (service_path != NULL, NULL); + + return g_object_new (TRACKER_TYPE_DBUS_SERVER, + "service-path", service_path, + NULL); +} + +gboolean +tracker_dbus_server_has_connection (TrackerDBusServer *server) +{ + TrackerDBusServerPrivate *priv; + + g_return_val_if_fail (TRACKER_IS_DBUS_SERVER (server), FALSE); + + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (server); + + return (priv->connection != NULL); +} + +static void +setup_env (gpointer user_data) +{ + TrackerDBusServer *server; + TrackerDBusServerPrivate *priv; + + server = TRACKER_DBUS_SERVER (user_data); + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (server); + + setenv ("TRACKER_PRIVATE_ADDRESS", priv->address, 1); +} + +static gboolean +spawn_service (TrackerDBusServer *server) +{ + TrackerDBusServerPrivate *priv; + GError *error = NULL; + gchar *argv[2] = { 0 }; + gboolean spawned = TRUE; + GPid pid; + + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (server); + + argv[0] = priv->service_path; + + if (!g_spawn_async (NULL, argv, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + setup_env, server, &pid, &error)) { + g_critical ("Could not spawn service: %s", error->message); + g_error_free (error); + spawned = FALSE; + return FALSE; + } + + g_message ("Spawned service with PID %d\n", pid); + + return spawned; +} + +void +tracker_dbus_server_ensure_connection (TrackerDBusServer *server) +{ + TrackerDBusServerPrivate *priv; + + g_return_if_fail (TRACKER_IS_DBUS_SERVER (server)); + + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (server); + + if (priv->connection) { + return; + } + + if (!spawn_service (server)) { + return; + } + + while (!priv->connection) { + /* Await for the connection */ + g_main_context_iteration (NULL, TRUE); + } +} + +DBusGConnection * +tracker_dbus_server_get_connection (TrackerDBusServer *server) +{ + TrackerDBusServerPrivate *priv; + + g_return_val_if_fail (TRACKER_IS_DBUS_SERVER (server), NULL); + + priv = TRACKER_DBUS_SERVER_GET_PRIVATE (server); + + return priv->gconnection; +} diff --git a/src/libtracker-common/tracker-dbus-server.h b/src/libtracker-common/tracker-dbus-server.h new file mode 100644 index 0000000..b22acf6 --- /dev/null +++ b/src/libtracker-common/tracker-dbus-server.h @@ -0,0 +1,69 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org) + * Copyright (C) 2007, Michal Pryc (Michal Pryc Sun Com) + * Copyright (C) 2008, Nokia (urho konttori nokia com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __TRACKER_DBUS_SERVER_H__ +#define __TRACKER_DBUS_SERVER_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#if !defined (__LIBTRACKER_COMMON_INSIDE__) && !defined (TRACKER_COMPILATION) +#error "only must be included directly." +#endif + +#ifndef DBUS_API_SUBJECT_TO_CHANGE +#define DBUS_API_SUBJECT_TO_CHANGE +#endif + +#define TRACKER_TYPE_DBUS_SERVER (tracker_dbus_server_get_type ()) +#define TRACKER_DBUS_SERVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DBUS_SERVER, TrackerDBusServer)) +#define TRACKER_DBUS_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), TRACKER_TYPE_DBUS_SERVER, TrackerDBusServerClass)) +#define TRACKER_IS_DBUS_SERVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DBUS_SERVER)) +#define TRACKER_IS_DBUS_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_DBUS_SERVER)) +#define TRACKER_DBUS_SERVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DBUS_SERVER, TrackerDBusServerClass)) + +typedef struct TrackerDBusServer TrackerDBusServer; +typedef struct TrackerDBusServerClass TrackerDBusServerClass; + +struct TrackerDBusServer { + GObject parent_instance; +}; + +struct TrackerDBusServerClass { + GObjectClass parent_class; +}; + +GType tracker_dbus_server_get_type (void) G_GNUC_CONST; + +TrackerDBusServer * tracker_dbus_server_new (const gchar *service_path); + +gboolean tracker_dbus_server_has_connection (TrackerDBusServer *server); +void tracker_dbus_server_ensure_connection (TrackerDBusServer *server); +DBusGConnection * tracker_dbus_server_get_connection (TrackerDBusServer *server); + + +G_END_DECLS + +#endif /* __TRACKER_DBUS_SERVER_H__ */ diff --git a/src/tracker-extract/tracker-dbus.c b/src/tracker-extract/tracker-dbus.c index e9cf7d3..9da0de5 100644 --- a/src/tracker-extract/tracker-dbus.c +++ b/src/tracker-extract/tracker-dbus.c @@ -90,6 +90,7 @@ static gboolean dbus_register_names (void) { GError *error = NULL; + const gchar *address; if (connection) { g_critical ("The DBusGConnection is already set, have we already initialized?"); @@ -101,7 +102,13 @@ dbus_register_names (void) return FALSE; } - connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + address = getenv ("TRACKER_PRIVATE_ADDRESS"); + + if (address) { + connection = dbus_g_connection_open (address, &error); + } else { + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + } if (!connection) { g_critical ("Could not connect to the DBus session bus, %s", @@ -110,17 +117,19 @@ dbus_register_names (void) return FALSE; } - /* The definitions below (DBUS_SERVICE_DBUS, etc) are - * predefined for us to just use (dbus_g_proxy_...) - */ - gproxy = dbus_g_proxy_new_for_name (connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - - /* Register the service name for org.freedesktop.Tracker.Extract */ - if (!dbus_register_service (gproxy, TRACKER_EXTRACT_SERVICE)) { - return FALSE; + if (!address) { + /* The definitions below (DBUS_SERVICE_DBUS, etc) are + * predefined for us to just use (dbus_g_proxy_...) + */ + gproxy = dbus_g_proxy_new_for_name (connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + + /* Register the service name for org.freedesktop.Tracker.Extract */ + if (!dbus_register_service (gproxy, TRACKER_EXTRACT_SERVICE)) { + return FALSE; + } } return TRUE; @@ -164,7 +173,7 @@ tracker_dbus_register_objects (void) { gpointer object; - if (!connection || !gproxy) { + if (!connection) { g_critical ("DBus support must be initialized before registering objects!"); return FALSE; } diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c index 5b5d31f..74305e3 100644 --- a/src/tracker-extract/tracker-main.c +++ b/src/tracker-extract/tracker-main.c @@ -52,7 +52,7 @@ "\n" \ " http://www.gnu.org/licenses/gpl.txt\n" -#define QUIT_TIMEOUT 30 /* 1/2 minutes worth of seconds */ +#define QUIT_TIMEOUT 3000000 /* 1/2 minutes worth of seconds */ static GMainLoop *main_loop; static guint quit_timeout_id; diff --git a/src/tracker-indexer/tracker-dbus.c b/src/tracker-indexer/tracker-dbus.c index 932fb24..2d56247 100644 --- a/src/tracker-indexer/tracker-dbus.c +++ b/src/tracker-indexer/tracker-dbus.c @@ -22,6 +22,7 @@ #include "config.h" #include +#include #include @@ -47,7 +48,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); @@ -94,6 +95,7 @@ dbus_register_object (GObject *object, dbus_g_object_type_install_info (G_OBJECT_TYPE (object), info); dbus_g_connection_register_g_object (connection, path, object); +#if 0 dbus_g_proxy_add_signal (proxy, "NameOwnerChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); @@ -101,6 +103,7 @@ dbus_register_object (GObject *object, dbus_g_proxy_connect_signal (proxy, "NameOwnerChanged", G_CALLBACK (name_owner_changed_cb), object, NULL); +#endif return TRUE; } @@ -108,6 +111,7 @@ static gboolean dbus_register_names (void) { GError *error = NULL; + gchar *address; if (connection) { g_critical ("The DBusGConnection is already set, have we already initialized?"); @@ -119,7 +123,13 @@ dbus_register_names (void) return FALSE; } - connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + address = getenv ("TRACKER_PRIVATE_ADDRESS"); + + if (address) { + connection = dbus_g_connection_open (address, &error); + } else { + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + } if (!connection) { g_critical ("Could not connect to the DBus session bus, %s", @@ -128,17 +138,19 @@ dbus_register_names (void) return FALSE; } - /* The definitions below (DBUS_SERVICE_DBUS, etc) are - * predefined for us to just use (dbus_g_proxy_...) - */ - gproxy = dbus_g_proxy_new_for_name (connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - - /* Register the service name for org.freedesktop.Tracker */ - if (!dbus_register_service (gproxy, TRACKER_INDEXER_SERVICE)) { - return FALSE; + if (!address) { + /* The definitions below (DBUS_SERVICE_DBUS, etc) are + * predefined for us to just use (dbus_g_proxy_...) + */ + gproxy = dbus_g_proxy_new_for_name (connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + + /* Register the service name for org.freedesktop.Tracker */ + if (!dbus_register_service (gproxy, TRACKER_INDEXER_SERVICE)) { + return FALSE; + } } return TRUE; @@ -174,7 +186,7 @@ tracker_dbus_shutdown (void) gboolean tracker_dbus_register_object (GObject *object) { - if (!connection || !gproxy) { + if (!connection) { g_critical ("DBus support must be initialized before registering objects!"); return FALSE; } diff --git a/src/tracker-indexer/tracker-indexer.c b/src/tracker-indexer/tracker-indexer.c index b214d3a..0935a79 100644 --- a/src/tracker-indexer/tracker-indexer.c +++ b/src/tracker-indexer/tracker-indexer.c @@ -725,10 +725,10 @@ check_stopped (TrackerIndexer *indexer, /* Print out how long it took us */ str = tracker_seconds_to_string (seconds_elapsed, FALSE); - g_message ("Indexer finished in %s, %d items processed in total (%d indexed)", + g_message ("Indexer finished in %s, %d items processed in total (%d indexed) %d", str, indexer->private->items_processed, - indexer->private->items_indexed); + indexer->private->items_indexed, interrupted); g_free (str); /* Finally signal done */ diff --git a/src/tracker-indexer/tracker-main.c b/src/tracker-indexer/tracker-main.c index ef2d5b0..ed21753 100644 --- a/src/tracker-indexer/tracker-main.c +++ b/src/tracker-indexer/tracker-main.c @@ -273,6 +273,7 @@ quit_timeout_cb (gpointer user_data) static void indexer_finished_cb (TrackerIndexer *indexer, gdouble seconds_elapsed, + guint items_processed, guint items_indexed, gboolean interrupted, gpointer user_data) diff --git a/src/tracker-indexer/tracker-module-metadata-utils.c b/src/tracker-indexer/tracker-module-metadata-utils.c index be59804..9401922 100644 --- a/src/tracker-indexer/tracker-module-metadata-utils.c +++ b/src/tracker-indexer/tracker-module-metadata-utils.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "tracker-module-metadata-utils.h" #include "tracker-extract-client.h" @@ -63,8 +64,9 @@ static ProcessContext *metadata_context = NULL; static DBusGProxy * get_dbus_extract_proxy (void) { + static TrackerDBusServer *server; static DBusGProxy *proxy = NULL; - DBusGConnection *connection; + static DBusGConnection *connection, *new_conn; GError *error = NULL; /* FIXME: Not perfect, we leak */ @@ -72,6 +74,23 @@ get_dbus_extract_proxy (void) return proxy; } + if (!server) { + server = tracker_dbus_server_new (LIBEXEC_PATH "/tracker-extract"); + } + + tracker_dbus_server_ensure_connection (server); + new_conn = tracker_dbus_server_get_connection (server); + + if (connection != new_conn) { + connection = new_conn; + g_object_unref (proxy); + + proxy = dbus_g_proxy_new_for_peer (connection, + "/org/freedesktop/Tracker/Extract", + "org.freedesktop.Tracker.Extract"); + } + +#if 0 connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); if (!connection) { @@ -86,6 +105,7 @@ get_dbus_extract_proxy (void) "org.freedesktop.Tracker.Extract", "/org/freedesktop/Tracker/Extract", "org.freedesktop.Tracker.Extract"); +#endif if (!proxy) { g_critical ("Couldn't create a DBusGProxy to the extract service"); diff --git a/src/trackerd/Makefile.am b/src/trackerd/Makefile.am index 87a0004..12bc9c8 100644 --- a/src/trackerd/Makefile.am +++ b/src/trackerd/Makefile.am @@ -4,6 +4,7 @@ INCLUDES = \ -DSHAREDIR=\""$(datadir)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DLOCALEDIR=\""$(localedir)"\" \ + -DLIBEXEC_PATH=\""$(libexecdir)"\" \ -DMAIL_MODULES_DIR=\""$(libdir)"/tracker/mail-modules\" \ -DPUSH_MODULES_DIR=\""$(libdir)/tracker/push-modules/daemon"\" \ -DG_LOG_DOMAIN=\"Tracker\" \ diff --git a/src/trackerd/tracker-dbus.c b/src/trackerd/tracker-dbus.c index 2efd17d..f5b9e34 100644 --- a/src/trackerd/tracker-dbus.c +++ b/src/trackerd/tracker-dbus.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -51,6 +52,7 @@ #define INDEXER_PAUSE_TIME_FOR_REQUESTS 10 /* seconds */ +static TrackerDBusServer *server_for_indexer; static DBusGConnection *connection; static DBusGProxy *gproxy; static DBusGProxy *proxy_for_indexer; @@ -263,6 +265,19 @@ dbus_request_new_cb (guint request_id, } } +static void +tracker_dbus_server_connection_notify (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + if (!tracker_dbus_server_has_connection (server_for_indexer)) { + if (proxy_for_indexer) { + g_object_unref (proxy_for_indexer); + proxy_for_indexer = NULL; + } + } +} + gboolean tracker_dbus_init (TrackerConfig *config) { @@ -278,6 +293,10 @@ tracker_dbus_init (TrackerConfig *config) return FALSE; } + server_for_indexer = tracker_dbus_server_new (LIBEXEC_PATH "/tracker-indexer"); + g_signal_connect (server_for_indexer, "notify::has-connection", + G_CALLBACK (tracker_dbus_server_connection_notify), NULL); + /* Register request handler so we can pause the indexer */ tracker_dbus_request_add_hook (dbus_request_new_cb, NULL, @@ -305,6 +324,11 @@ tracker_dbus_shutdown (void) proxy_for_indexer = NULL; } + if (server_for_indexer) { + g_object_unref (server_for_indexer); + server_for_indexer = NULL; + } + connection = NULL; } @@ -445,17 +469,32 @@ tracker_dbus_get_object (GType type) DBusGProxy * tracker_dbus_indexer_get_proxy (void) { - if (!connection) { + if (!server_for_indexer) { g_critical ("DBus support must be initialized before starting the indexer!"); return NULL; } if (!proxy_for_indexer) { + DBusGConnection *connection; + + tracker_dbus_server_ensure_connection (server_for_indexer); + connection = tracker_dbus_server_get_connection (server_for_indexer); + + if (G_UNLIKELY (!connection)) { + g_critical ("Communication with the indexer service is broken"); + return NULL; + } + /* Get proxy for Service / Path / Interface of the indexer */ + proxy_for_indexer = dbus_g_proxy_new_for_peer (connection, + "/org/freedesktop/Tracker/Indexer", + "org.freedesktop.Tracker.Indexer"); +#if 0 proxy_for_indexer = dbus_g_proxy_new_for_name (connection, "org.freedesktop.Tracker.Indexer", "/org/freedesktop/Tracker/Indexer", "org.freedesktop.Tracker.Indexer"); +#endif if (!proxy_for_indexer) { g_critical ("Couldn't create a DBusGProxy to the indexer service"); diff --git a/src/trackerd/tracker-processor.c b/src/trackerd/tracker-processor.c index 2253322..019dfcb 100644 --- a/src/trackerd/tracker-processor.c +++ b/src/trackerd/tracker-processor.c @@ -113,6 +113,7 @@ static void tracker_processor_finalize (GObject *object); static void crawler_destroy_notify (gpointer data); static void item_queue_destroy_notify (gpointer data); static void process_module_next (TrackerProcessor *processor); +static void tracker_processor_update_proxy (TrackerProcessor *processor); static void indexer_status_cb (DBusGProxy *proxy, gdouble seconds_elapsed, const gchar *current_module_name, @@ -164,6 +165,7 @@ static void crawler_finished_cb (TrackerCrawler *crawler, guint files_ignored, gpointer user_data); + #ifdef HAVE_HAL static void mount_point_added_cb (TrackerHal *hal, const gchar *volume_uuid, @@ -300,13 +302,15 @@ tracker_processor_finalize (GObject *object) g_list_free (priv->modules); - dbus_g_proxy_disconnect_signal (priv->indexer_proxy, "Finished", - G_CALLBACK (indexer_finished_cb), - NULL); - dbus_g_proxy_disconnect_signal (priv->indexer_proxy, "Status", - G_CALLBACK (indexer_status_cb), - NULL); - g_object_unref (priv->indexer_proxy); + if (priv->indexer_proxy) { + dbus_g_proxy_disconnect_signal (priv->indexer_proxy, "Finished", + G_CALLBACK (indexer_finished_cb), + NULL); + dbus_g_proxy_disconnect_signal (priv->indexer_proxy, "Status", + G_CALLBACK (indexer_status_cb), + NULL); + g_object_unref (priv->indexer_proxy); + } g_signal_handlers_disconnect_by_func (priv->monitor, G_CALLBACK (monitor_item_deleted_cb), @@ -597,6 +601,7 @@ item_queue_handlers_cb (gpointer user_data) gchar *module_name; processor = user_data; + tracker_processor_update_proxy (processor); /* This way we don't send anything to the indexer from monitor * events but we still queue them ready to send when we are @@ -1614,6 +1619,45 @@ mount_point_removed_cb (TrackerHal *hal, #endif /* HAVE_HAL */ +static void +tracker_processor_update_proxy (TrackerProcessor *processor) +{ + TrackerProcessorPrivate *priv; + DBusGProxy *proxy; + + /* Set up the indexer proxy and signalling to know when we are + * finished. + */ + priv = processor->private; + proxy = tracker_dbus_indexer_get_proxy (); + + if (proxy != priv->indexer_proxy) { + if (priv->indexer_proxy) { + dbus_g_proxy_disconnect_signal (priv->indexer_proxy, "Finished", + G_CALLBACK (indexer_finished_cb), + NULL); + dbus_g_proxy_disconnect_signal (priv->indexer_proxy, "Status", + G_CALLBACK (indexer_status_cb), + NULL); + g_object_unref (priv->indexer_proxy); + priv->indexer_proxy = NULL; + } + + if (proxy) { + priv->indexer_proxy = g_object_ref (proxy); + + dbus_g_proxy_connect_signal (proxy, "Finished", + G_CALLBACK (indexer_finished_cb), + processor, + NULL); + dbus_g_proxy_connect_signal (proxy, "Status", + G_CALLBACK (indexer_status_cb), + processor, + NULL); + } + } +} + TrackerProcessor * tracker_processor_new (TrackerConfig *config, TrackerHal *hal) @@ -1621,7 +1665,6 @@ tracker_processor_new (TrackerConfig *config, TrackerProcessor *processor; TrackerProcessorPrivate *priv; TrackerCrawler *crawler; - DBusGProxy *proxy; GList *l; g_return_val_if_fail (TRACKER_IS_CONFIG (config), NULL); @@ -1695,17 +1738,7 @@ tracker_processor_new (TrackerConfig *config, /* Set up the indexer proxy and signalling to know when we are * finished. */ - proxy = tracker_dbus_indexer_get_proxy (); - priv->indexer_proxy = g_object_ref (proxy); - - dbus_g_proxy_connect_signal (proxy, "Status", - G_CALLBACK (indexer_status_cb), - processor, - NULL); - dbus_g_proxy_connect_signal (proxy, "Finished", - G_CALLBACK (indexer_finished_cb), - processor, - NULL); + tracker_processor_update_proxy (processor); return processor; }