[gnome-notes] manager: Create manager in main thread
- From: Isaque Galdino de Araujo <igaldino src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-notes] manager: Create manager in main thread
- Date: Tue, 30 Mar 2021 22:01:56 +0000 (UTC)
commit bc7eef0f51b4541e7e4c1bf840ba41b7d8ab2d2a
Author: Mohammed Sadiq <sadiq sadiqpk org>
Date: Wed Mar 17 07:33:07 2021 +0530
manager: Create manager in main thread
And adapt accordingly.
We were using GAsyncInitable to create the manager, and all signals
were hooked in some different thread, which resulted in the variables
in manager being accessed/modified both in non-UI thread and in UI
thread (when manager methods were called by some UI thread). This
could be the reason of occasional crashes happening to many.
So instead, always create the manager and load providers async, and
add the providers in main thread itself. Also, make manager a plain
GObject since we no longer require it to be initalized async.
In the future this can help let the main window be always shown and
update according to the errors/status reported by the manager.
src/bijiben-shell-search-provider.c | 28 +++-
src/bjb-application.c | 6 +-
src/libbiji/biji-manager.c | 259 +++++++++++++++++++-----------------
src/libbiji/biji-manager.h | 18 +--
4 files changed, 177 insertions(+), 134 deletions(-)
---
diff --git a/src/bijiben-shell-search-provider.c b/src/bijiben-shell-search-provider.c
index 387b768..35417ee 100644
--- a/src/bijiben-shell-search-provider.c
+++ b/src/bijiben-shell-search-provider.c
@@ -347,6 +347,24 @@ handle_activate_result (BijibenShellSearchProvider2 *skeleton,
g_application_release (user_data);
}
+static void
+shell_search_load_providers_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GTask *task = user_data;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (G_IS_TASK (task));
+
+ biji_manager_load_providers_finish (BIJI_MANAGER (object), result, &error);
+
+ if (error)
+ g_warning ("Error loading providers: %s", error->message);
+
+ g_task_return_boolean (task, TRUE);
+}
+
static void
search_provider_app_dbus_unregister (GApplication *application,
GDBusConnection *connection,
@@ -421,6 +439,7 @@ bijiben_shell_search_provider_app_init (BijibenShellSearchProviderApp *self)
char *storage_path;
GFile *storage;
GdkRGBA color = { 0, 0, 0, 0 };
+ g_autoptr(GTask) task = NULL;
#ifdef TRACKER_PRIVATE_STORE
g_autofree char *filename = NULL;
g_autoptr (GFile) data_location = NULL;
@@ -462,9 +481,16 @@ bijiben_shell_search_provider_app_init (BijibenShellSearchProviderApp *self)
storage = g_file_new_for_path (storage_path);
g_free (storage_path);
- self->manager = biji_manager_new (storage, &color, &error);
+ self->manager = biji_manager_new (storage, &color);
g_object_unref (storage);
+ task = g_task_new (self, NULL, NULL, NULL);
+ biji_manager_load_providers_async (self->manager, shell_search_load_providers_cb, task);
+
+ /* Wait until the task is completed */
+ while (!g_task_get_completed (task))
+ g_main_context_iteration (NULL, TRUE);
+
if (error)
{
g_warning ("Unable to create BijiManager: %s", error->message);
diff --git a/src/bjb-application.c b/src/bjb-application.c
index 6792d1c..22cf723 100644
--- a/src/bjb-application.c
+++ b/src/bjb-application.c
@@ -317,7 +317,7 @@ manager_ready_cb (GObject *source,
g_autofree gchar *path = NULL;
g_autofree gchar *uri = NULL;
- self->manager = biji_manager_new_finish (res, &error);
+ biji_manager_load_providers_finish (self->manager, res, &error);
g_application_release (G_APPLICATION (self));
if (error != NULL)
@@ -419,7 +419,9 @@ bijiben_startup (GApplication *application)
NULL);
g_application_hold (application);
- biji_manager_new_async (storage, &color, manager_ready_cb, self);
+
+ self->manager = biji_manager_new (storage, &color);
+ biji_manager_load_providers_async (self->manager, manager_ready_cb, self);
}
static gboolean
diff --git a/src/libbiji/biji-manager.c b/src/libbiji/biji-manager.c
index b821ce7..2115d61 100644
--- a/src/libbiji/biji-manager.c
+++ b/src/libbiji/biji-manager.c
@@ -70,12 +70,8 @@ enum {
static guint biji_manager_signals[BIJI_MANAGER_SIGNALS] = { 0 };
static GParamSpec *properties[BIJI_MANAGER_PROPERTIES] = { NULL, };
-static void biji_manager_initable_iface_init (GInitableIface *iface);
-static void biji_manager_async_initable_iface_init (GAsyncInitableIface *iface);
-G_DEFINE_TYPE_WITH_CODE (BijiManager, biji_manager, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, biji_manager_initable_iface_init)
- G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
biji_manager_async_initable_iface_init))
+G_DEFINE_TYPE (BijiManager, biji_manager, G_TYPE_OBJECT)
static void
on_provider_loaded_cb (BijiProvider *provider,
@@ -203,96 +199,6 @@ load_eds_registry (BijiManager *self,
g_list_free_full (list, g_object_unref);
}
-static gboolean
-biji_manager_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
-{
- BijiManager *self = BIJI_MANAGER (initable);
- GError *local_error = NULL;
- GoaClient *client;
- ESourceRegistry *registry;
-#ifdef TRACKER_PRIVATE_STORE
- g_autofree char *filename = NULL;
- g_autoptr (GFile) data_location = NULL;
-
- filename = g_build_filename (g_get_user_cache_dir (),
- g_get_application_name (),
-#if HAVE_TRACKER3
- "tracker3",
-#else
- "tracker",
-#endif /* HAVE_TRACKER3 */
- NULL);
- data_location = g_file_new_for_path (filename);
-
- /* If tracker fails for some reason,
- * do not attempt anything */
-#if HAVE_TRACKER3
- self->connection = tracker_sparql_connection_new (TRACKER_SPARQL_CONNECTION_FLAGS_NONE,
- data_location,
- tracker_sparql_get_ontology_nepomuk (),
- NULL,
- &local_error);
-#else
- self->connection = tracker_sparql_connection_local_new (TRACKER_SPARQL_CONNECTION_FLAGS_NONE,
- data_location,
- NULL, NULL, NULL,
- &local_error);
-#endif /* HAVE_TRACKER3 */
-
-#else
- self->connection = tracker_sparql_connection_get (NULL, &local_error);
-#endif /* TRACKER_PRIVATE_STORE */
-
- if (local_error)
- {
- g_warning ("Unable to connect to Tracker: %s", local_error->message);
- g_propagate_error (error, local_error);
- return FALSE;
- }
-
- client = goa_client_new_sync (NULL, &local_error);
- if (local_error)
- {
- g_warning ("Unable to connect to GOA: %s", local_error->message);
- g_propagate_error (error, local_error);
- return FALSE;
- }
-
- registry = e_source_registry_new_sync (NULL, &local_error);
- if (local_error)
- {
- g_object_unref (client);
- g_warning ("Unable to connect to EDS: %s", local_error->message);
- g_propagate_error (error, local_error);
- return FALSE;
- }
-
- self->local_provider = biji_local_provider_new (self, self->location);
- _add_provider (self, self->local_provider);
-
- load_goa_client (self, client);
- load_eds_registry (self, registry);
-
- g_object_unref (client);
- g_object_unref (registry);
-
- return TRUE;
-}
-
-static void
-biji_manager_initable_iface_init (GInitableIface *iface)
-{
- iface->init = biji_manager_initable_init;
-}
-
-static void
-biji_manager_async_initable_iface_init (GAsyncInitableIface *iface)
-{
- /* Use default */
-}
-
static void
biji_manager_init (BijiManager *self)
{
@@ -794,42 +700,155 @@ biji_manager_remove_item_at_path (BijiManager *self,
}
BijiManager *
-biji_manager_new (GFile *location, GdkRGBA *color, GError **error)
+biji_manager_new (GFile *location,
+ GdkRGBA *color)
{
- BijiManager *retval;
+ return g_object_new (BIJI_TYPE_MANAGER,
+ "location", location,
+ "color", color,
+ NULL);
+}
- retval = g_initable_new (BIJI_TYPE_MANAGER, NULL, error,
- "location", location,
- "color", color,
- NULL);
+static void
+thread_run_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ BijiManager *self = user_data;
+ g_autoptr(GTask) task = NULL;
+ ESourceRegistry *registry;
+ GoaClient *client;
+ GError *error = NULL;
- return retval;
+ g_assert (BIJI_IS_MANAGER (self));
+ g_assert (G_IS_TASK (result));
+
+ task = g_task_get_task_data (G_TASK (result));
+ g_object_ref (task);
+
+ g_task_propagate_boolean (G_TASK (result), &error);
+
+ if (error)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ client = g_object_get_data (G_OBJECT (result), "goa");
+ registry = g_object_get_data (G_OBJECT (result), "eds");
+ g_assert (client);
+ g_assert (registry);
+
+ load_goa_client (self, client);
+ load_eds_registry (self, registry);
+
+ g_task_return_boolean (task, TRUE);
+}
+
+static void
+load_providers (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ BijiManager *self = source_object;
+ g_autoptr(GoaClient) client = NULL;
+ GError *error = NULL;
+ ESourceRegistry *registry;
+#ifdef TRACKER_PRIVATE_STORE
+ g_autofree char *filename = NULL;
+ g_autoptr(GFile) data_location = NULL;
+
+ filename = g_build_filename (g_get_user_cache_dir (),
+ g_get_application_name (),
+#if HAVE_TRACKER3
+ "tracker3",
+#else
+ "tracker",
+#endif /* HAVE_TRACKER3 */
+ NULL);
+ data_location = g_file_new_for_path (filename);
+
+ g_assert (BIJI_IS_MANAGER (self));
+ g_assert (G_IS_TASK (task));
+
+ /* If tracker fails for some reason,
+ * do not attempt anything */
+#if HAVE_TRACKER3
+ self->connection = tracker_sparql_connection_new (TRACKER_SPARQL_CONNECTION_FLAGS_NONE,
+ data_location,
+ tracker_sparql_get_ontology_nepomuk (),
+ NULL,
+ &error);
+#else
+ self->connection = tracker_sparql_connection_local_new (TRACKER_SPARQL_CONNECTION_FLAGS_NONE,
+ data_location,
+ NULL, NULL, NULL,
+ &error);
+#endif /* HAVE_TRACKER3 */
+
+#else
+ self->connection = tracker_sparql_connection_get (NULL, &error);
+#endif /* TRACKER_PRIVATE_STORE */
+
+ if (error)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ client = goa_client_new_sync (NULL, &error);
+ if (error)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ registry = e_source_registry_new_sync (NULL, &error);
+ if (error)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ self->local_provider = biji_local_provider_new (self, self->location);
+ _add_provider (self, self->local_provider);
+
+ g_object_ref (client);
+ g_object_set_data_full (G_OBJECT (task), "goa", client, g_object_unref);
+ g_object_set_data_full (G_OBJECT (task), "eds", registry, g_object_unref);
+
+ g_task_return_boolean (task, TRUE);
+
+ return;
}
void
-biji_manager_new_async (GFile *location, GdkRGBA *color,
- GAsyncReadyCallback callback, gpointer user_data)
+biji_manager_load_providers_async (BijiManager *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- g_async_initable_new_async (BIJI_TYPE_MANAGER, G_PRIORITY_DEFAULT,
- NULL,
- callback, user_data,
- "location", location,
- "color", color,
- NULL);
+ g_autoptr(GTask) thread_task = NULL;
+ GTask *task;
+
+ g_return_if_fail (BIJI_IS_MANAGER (self));
+
+ task = g_task_new (self, NULL, callback, user_data);
+ thread_task = g_task_new (self, NULL, thread_run_cb, self);
+ g_task_set_task_data (thread_task, task, g_object_unref);
+
+ g_task_run_in_thread (thread_task, load_providers);
}
-BijiManager *
-biji_manager_new_finish (GAsyncResult *res,
- GError **error)
+gboolean
+biji_manager_load_providers_finish (BijiManager *self,
+ GAsyncResult *result,
+ GError **error)
{
- GObject *source_obj;
- GObject *object;
-
- source_obj = g_async_result_get_source_object (res);
- object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_obj), res, error);
- g_object_unref (source_obj);
+ g_return_val_if_fail (BIJI_IS_MANAGER (self), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
- return object != NULL ? BIJI_MANAGER (object) : NULL;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
/* Create the importer == switch depending on the uri.
diff --git a/src/libbiji/biji-manager.h b/src/libbiji/biji-manager.h
index d1066b7..793cc6f 100644
--- a/src/libbiji/biji-manager.h
+++ b/src/libbiji/biji-manager.h
@@ -40,18 +40,14 @@ typedef enum
G_DECLARE_FINAL_TYPE (BijiManager, biji_manager, BIJI, MANAGER, GObject)
-BijiManager *biji_manager_new (GFile *location,
- GdkRGBA *color,
- GError **error);
-
-void biji_manager_new_async (GFile *location,
- GdkRGBA *color,
+BijiManager *biji_manager_new (GFile *location,
+ GdkRGBA *color);
+void biji_manager_load_providers_async (BijiManager *self,
GAsyncReadyCallback callback,
- gpointer user_data);
-
-BijiManager *biji_manager_new_finish (GAsyncResult *res,
- GError **error);
-
+ gpointer user_data);
+gboolean biji_manager_load_providers_finish (BijiManager *self,
+ GAsyncResult *result,
+ GError **error);
void biji_manager_import_uri (BijiManager *manager,
const gchar *target_provider_id,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]