[gnome-photos] application: Create the miner proxies asynchronously & only when needed
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-photos] application: Create the miner proxies asynchronously & only when needed
- Date: Fri, 23 Oct 2015 07:32:53 +0000 (UTC)
commit e59e6905b5f3277d4029704d9b2a0eb36be6508a
Author: Debarshi Ray <debarshir gnome org>
Date: Wed Feb 18 03:11:00 2015 +0100
application: Create the miner proxies asynchronously & only when needed
We only need them when an application window is shown, so there is no
point in creating the miner proxies during startup which is shared
between the search provider and the application. So, let's tie them to
the lifetime of the window.
Plus, creating them asynchronously is the right thing to do, and we
can't sneak in G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES because we use
the properties.
https://bugzilla.gnome.org/show_bug.cgi?id=744627
src/photos-application.c | 220 +++++++++++++++++++++++++++++++++++-----------
1 files changed, 170 insertions(+), 50 deletions(-)
---
diff --git a/src/photos-application.c b/src/photos-application.c
index eb1026f..75ac8c6 100644
--- a/src/photos-application.c
+++ b/src/photos-application.c
@@ -60,6 +60,7 @@
struct _PhotosApplicationPrivate
{
+ GCancellable *create_miners_cancellable;
GList *miners;
GList *miners_running;
GResource *resource;
@@ -84,7 +85,10 @@ struct _PhotosApplicationPrivate
PhotosSearchContextState *state;
PhotosSearchProvider *search_provider;
TrackerExtractPriority *extract_priority;
+ guint create_miners_count;
guint32 activation_timestamp;
+ gulong source_added_id;
+ gulong source_removed_id;
};
enum
@@ -117,8 +121,16 @@ static const gchar *DESKTOP_KEY_COLOR_SHADING_TYPE = "color-shading-type";
static const gchar *DESKTOP_KEY_PRIMARY_COLOR = "primary-color";
static const gchar *DESKTOP_KEY_SECONDARY_COLOR = "secondary-color";
+typedef struct _PhotosApplicationCreateData PhotosApplicationCreateData;
typedef struct _PhotosApplicationRefreshData PhotosApplicationRefreshData;
+struct _PhotosApplicationCreateData
+{
+ PhotosApplication *application;
+ gchar *extension_name;
+ gchar *miner_name;
+};
+
struct _PhotosApplicationRefreshData
{
PhotosApplication *application;
@@ -127,9 +139,35 @@ struct _PhotosApplicationRefreshData
static gboolean photos_application_refresh_miner_now (PhotosApplication *self, GomMiner *miner);
static void photos_application_start_miners (PhotosApplication *self);
+static void photos_application_start_miners_second (PhotosApplication *self);
static void photos_application_stop_miners (PhotosApplication *self);
+static PhotosApplicationCreateData *
+photos_application_create_data_new (PhotosApplication *application,
+ const gchar *extension_name,
+ const gchar *miner_name)
+{
+ PhotosApplicationCreateData *data;
+
+ data = g_slice_new0 (PhotosApplicationCreateData);
+ data->application = g_object_ref (application);
+ data->extension_name = g_strdup (extension_name);
+ data->miner_name = g_strdup (miner_name);
+ return data;
+}
+
+
+static void
+photos_application_create_data_free (PhotosApplicationCreateData *data)
+{
+ g_object_unref (data->application);
+ g_free (data->extension_name);
+ g_free (data->miner_name);
+ g_slice_free (PhotosApplicationCreateData, data);
+}
+
+
static PhotosApplicationRefreshData *
photos_application_refresh_data_new (PhotosApplication *application, GomMiner *miner)
{
@@ -196,6 +234,84 @@ photos_application_destroy (PhotosApplication *self)
static void
+photos_application_gom_miner (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ PhotosApplicationCreateData *data = (PhotosApplicationCreateData *) user_data;
+ PhotosApplication *self = data->application;
+ PhotosApplicationPrivate *priv = self->priv;
+ GError *error;
+ GomMiner *miner = NULL;
+
+ error = NULL;
+ miner = gom_miner_proxy_new_for_bus_finish (res, &error);
+ if (error != NULL)
+ {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ {
+ g_error_free (error);
+ goto out;
+ }
+ else
+ {
+ g_warning ("Unable to create GomMiner proxy for %s: %s", data->miner_name, error->message);
+ g_error_free (error);
+ goto maybe_continue;
+ }
+ }
+
+ g_object_set_data_full (G_OBJECT (miner), "provider-type", g_strdup (data->extension_name), g_free);
+ priv->miners = g_list_prepend (priv->miners, g_object_ref (miner));
+
+ maybe_continue:
+ if (priv->create_miners_count == 1)
+ photos_application_start_miners_second (self);
+
+ out:
+ priv->create_miners_count--;
+ g_clear_object (&miner);
+ photos_application_create_data_free (data);
+}
+
+
+static void
+photos_application_create_miners (PhotosApplication *self)
+{
+ PhotosApplicationPrivate *priv = self->priv;
+ GIOExtensionPoint *extension_point;
+ GList *extensions;
+ GList *l;
+
+ extension_point = g_io_extension_point_lookup (PHOTOS_BASE_ITEM_EXTENSION_POINT_NAME);
+ extensions = g_io_extension_point_get_extensions (extension_point);
+ for (l = extensions; l != NULL; l = l->next)
+ {
+ GIOExtension *extension = (GIOExtension *) l->data;
+ PhotosApplicationCreateData *data;
+ PhotosBaseItemClass *base_item_class;
+
+ base_item_class = PHOTOS_BASE_ITEM_CLASS (g_io_extension_ref_class (extension));
+ if (base_item_class->miner_name != NULL && base_item_class->miner_object_path != NULL)
+ {
+ const gchar *extension_name;
+
+ extension_name = g_io_extension_get_name (extension);
+ data = photos_application_create_data_new (self, extension_name, base_item_class->miner_name);
+ gom_miner_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ base_item_class->miner_name,
+ base_item_class->miner_object_path,
+ priv->create_miners_cancellable,
+ photos_application_gom_miner,
+ data);
+ priv->create_miners_count++;
+ }
+
+ g_type_class_unref (base_item_class);
+ }
+}
+
+
+static void
photos_application_create_window (PhotosApplication *self)
{
PhotosApplicationPrivate *priv = self->priv;
@@ -533,20 +649,27 @@ photos_application_set_bg_common (PhotosApplication *self, GVariant *parameter,
static void
photos_application_start_miners (PhotosApplication *self)
{
+ photos_application_create_miners (self);
+}
+
+
+static void
+photos_application_start_miners_second (PhotosApplication *self)
+{
PhotosApplicationPrivate *priv = self->priv;
photos_application_refresh_miners (self);
- g_signal_connect_object (priv->state->src_mngr,
- "object-added",
- G_CALLBACK (photos_application_refresh_miners),
- self,
- G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->state->src_mngr,
- "object-removed",
- G_CALLBACK (photos_application_refresh_miners),
- self,
- G_CONNECT_SWAPPED);
+ priv->source_added_id = g_signal_connect_object (priv->state->src_mngr,
+ "object-added",
+ G_CALLBACK (photos_application_refresh_miners),
+ self,
+ G_CONNECT_SWAPPED);
+ priv->source_removed_id = g_signal_connect_object (priv->state->src_mngr,
+ "object-removed",
+ G_CALLBACK (photos_application_refresh_miners),
+ self,
+ G_CONNECT_SWAPPED);
}
@@ -556,6 +679,10 @@ photos_application_stop_miners (PhotosApplication *self)
PhotosApplicationPrivate *priv = self->priv;
GList *l;
+ g_cancellable_cancel (priv->create_miners_cancellable);
+ g_clear_object (&priv->create_miners_cancellable);
+ priv->create_miners_cancellable = g_cancellable_new ();
+
for (l = priv->miners_running; l != NULL; l = l->next)
{
GomMiner *miner = GOM_MINER (l->data);
@@ -564,6 +691,21 @@ photos_application_stop_miners (PhotosApplication *self)
cancellable = g_object_get_data (G_OBJECT (miner), "cancellable");
g_cancellable_cancel (cancellable);
}
+
+ if (priv->source_added_id != 0)
+ {
+ g_signal_handler_disconnect (priv->state->src_mngr, priv->source_added_id);
+ priv->source_added_id = 0;
+ }
+
+ if (priv->source_removed_id != 0)
+ {
+ g_signal_handler_disconnect (priv->state->src_mngr, priv->source_removed_id);
+ priv->source_removed_id = 0;
+ }
+
+ g_list_free_full (priv->miners, g_object_unref);
+ priv->miners = NULL;
}
@@ -791,9 +933,6 @@ photos_application_startup (GApplication *application)
PhotosApplication *self = PHOTOS_APPLICATION (application);
PhotosApplicationPrivate *priv = self->priv;
GError *error;
- GIOExtensionPoint *extension_point;
- GList *extensions;
- GList *l;
GSimpleAction *action;
GrlRegistry *registry;
GtkSettings *settings;
@@ -819,6 +958,8 @@ photos_application_startup (GApplication *application)
g_error_free (error);
}
+ priv->create_miners_cancellable = g_cancellable_new ();
+
priv->bg_settings = g_settings_new (DESKTOP_BACKGROUND_SCHEMA);
priv->ss_settings = g_settings_new (DESKTOP_SCREENSAVER_SCHEMA);
@@ -830,43 +971,6 @@ photos_application_startup (GApplication *application)
g_signal_connect (settings, "notify::gtk-theme-name", G_CALLBACK (photos_application_theme_changed), NULL);
photos_application_theme_changed (settings);
- extension_point = g_io_extension_point_lookup (PHOTOS_BASE_ITEM_EXTENSION_POINT_NAME);
- extensions = g_io_extension_point_get_extensions (extension_point);
- for (l = extensions; l != NULL; l = l->next)
- {
- GIOExtension *extension = (GIOExtension *) l->data;
- PhotosBaseItemClass *base_item_class;
-
- base_item_class = PHOTOS_BASE_ITEM_CLASS (g_io_extension_ref_class (extension));
- if (base_item_class->miner_name != NULL && base_item_class->miner_object_path != NULL)
- {
- GomMiner *miner;
- const gchar *extension_name;
-
- error = NULL;
- miner = gom_miner_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- base_item_class->miner_name,
- base_item_class->miner_object_path,
- NULL,
- &error);
- if (error != NULL)
- {
- g_warning ("Unable to create GomMiner proxy for %s: %s", base_item_class->miner_name,
error->message);
- g_error_free (error);
- continue;
- }
-
- extension_name = g_io_extension_get_name (extension);
- g_object_set_data_full (G_OBJECT (miner), "provider-type", g_strdup (extension_name), g_free);
-
- priv->miners = g_list_prepend (priv->miners, g_object_ref (miner));
- g_object_unref (miner);
- }
-
- g_type_class_unref (base_item_class);
- }
-
tracker_extract_priority_proxy_new_for_bus (G_BUS_TYPE_SESSION,
G_DBUS_PROXY_FLAGS_NONE,
"org.freedesktop.Tracker1.Miner.Extract",
@@ -1030,6 +1134,7 @@ photos_application_dispose (GObject *object)
priv->resource = NULL;
}
+ g_clear_object (&priv->create_miners_cancellable);
g_clear_object (&priv->bg_settings);
g_clear_object (&priv->ss_settings);
g_clear_object (&priv->fs_action);
@@ -1059,6 +1164,20 @@ photos_application_dispose (GObject *object)
static void
+photos_application_finalize (GObject *object)
+{
+ PhotosApplication *self = PHOTOS_APPLICATION (object);
+ PhotosApplicationPrivate *priv = self->priv;
+
+ if (G_UNLIKELY (priv->create_miners_count != 0))
+ g_critical ("Application is being destroyed while %u miner proxies are still being created.",
+ priv->create_miners_count);
+
+ G_OBJECT_CLASS (photos_application_parent_class)->finalize (object);
+}
+
+
+static void
photos_application_init (PhotosApplication *self)
{
PhotosApplicationPrivate *priv;
@@ -1093,6 +1212,7 @@ photos_application_class_init (PhotosApplicationClass *class)
object_class->constructor = photos_application_constructor;
object_class->dispose = photos_application_dispose;
+ object_class->finalize = photos_application_finalize;
application_class->activate = photos_application_activate;
application_class->dbus_register = photos_application_dbus_register;
application_class->dbus_unregister = photos_application_dbus_unregister;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]