[evolution-data-server] Bug 685713 - ESourceRegistry's manager thread aborts on error
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 685713 - ESourceRegistry's manager thread aborts on error
- Date: Wed, 10 Oct 2012 12:51:05 +0000 (UTC)
commit f47e935e450c132a48d6945cd553ec24b794c708
Author: Matthew Barnes <mbarnes redhat com>
Date: Wed Oct 10 08:41:28 2012 -0400
Bug 685713 - ESourceRegistry's manager thread aborts on error
If the ESourceRegistry's manager thread fails to create a new
GDBusObjectManagerClient during initialization, propagate the GError
back to the caller of e_source_registry_new() instead of aborting the
whole process with a g_error() call.
libedataserver/e-source-registry.c | 72 +++++++++++++++++++++---------------
1 files changed, 42 insertions(+), 30 deletions(-)
---
diff --git a/libedataserver/e-source-registry.c b/libedataserver/e-source-registry.c
index b5632cd..3933712 100644
--- a/libedataserver/e-source-registry.c
+++ b/libedataserver/e-source-registry.c
@@ -146,6 +146,7 @@ struct _ThreadClosure {
GMainLoop *main_loop;
GCond *main_loop_cond;
GMutex *main_loop_mutex;
+ GError *error;
};
enum {
@@ -241,6 +242,10 @@ thread_closure_free (ThreadClosure *closure)
g_cond_free (closure->main_loop_cond);
g_mutex_free (closure->main_loop_mutex);
+ /* The GError should be NULL at this point,
+ * regardless of whether an error occurred. */
+ g_warn_if_fail (closure->error == NULL);
+
g_slice_free (ThreadClosure, closure);
}
@@ -711,9 +716,8 @@ source_registry_object_manager_thread (gpointer data)
ThreadClosure *closure = data;
GSource *idle_source;
GList *list, *link;
- gulong object_added_id;
- gulong object_removed_id;
- GError *error = NULL;
+ gulong object_added_id = 0;
+ gulong object_removed_id = 0;
/* GDBusObjectManagerClient grabs the thread-default GMainContext
* at creation time and only emits signals from that GMainContext.
@@ -731,15 +735,19 @@ source_registry_object_manager_thread (gpointer data)
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
SOURCES_DBUS_SERVICE_NAME,
DBUS_OBJECT_PATH,
- NULL, &error);
+ NULL, &closure->error);
- /* If this fails there's really no point in continuing
- * since we rely on the object manager to populate the
- * registry. Abort the process with a fatal error. */
- if (error != NULL) {
- g_error ("%s", error->message);
- g_assert_not_reached ();
- }
+ /* Sanity check. */
+ g_warn_if_fail (
+ ((object_manager != NULL) && (closure->error == NULL)) ||
+ ((object_manager == NULL) && (closure->error != NULL)));
+
+ /* If we failed to create the GDBusObjectManagerClient, skip
+ * straight to the main loop. The GError will be propagated
+ * back to the caller, the main loop will terminate, and the
+ * partially-initialized ESourceRegistry will be destroyed. */
+ if (object_manager == NULL)
+ goto notify;
/* Give the registry a handle to the object manager. */
closure->registry->priv->dbus_object_manager =
@@ -767,17 +775,6 @@ source_registry_object_manager_thread (gpointer data)
g_list_free_full (list, (GDestroyNotify) g_object_unref);
- /* Schedule a one-time idle callback to broadcast through a
- * condition variable that our main loop is up and running. */
-
- idle_source = g_idle_source_new ();
- g_source_set_callback (
- idle_source,
- source_registry_object_manager_running,
- closure, (GDestroyNotify) NULL);
- g_source_attach (idle_source, closure->main_context);
- g_source_unref (idle_source);
-
/* Listen for D-Bus object additions and removals. */
object_added_id = g_signal_connect (
@@ -790,16 +787,29 @@ source_registry_object_manager_thread (gpointer data)
G_CALLBACK (source_registry_object_removed_cb),
closure->registry);
+notify:
+ /* Schedule a one-time idle callback to broadcast through a
+ * condition variable that our main loop is up and running. */
+
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (
+ idle_source,
+ source_registry_object_manager_running,
+ closure, (GDestroyNotify) NULL);
+ g_source_attach (idle_source, closure->main_context);
+ g_source_unref (idle_source);
+
/* Now we mostly idle here for the rest of the session. */
g_main_loop_run (closure->main_loop);
/* Clean up and exit. */
- g_signal_handler_disconnect (object_manager, object_added_id);
- g_signal_handler_disconnect (object_manager, object_removed_id);
-
- g_object_unref (object_manager);
+ if (object_manager != NULL) {
+ g_signal_handler_disconnect (object_manager, object_added_id);
+ g_signal_handler_disconnect (object_manager, object_removed_id);
+ g_object_unref (object_manager);
+ }
g_main_context_pop_thread_default (closure->main_context);
@@ -1005,10 +1015,12 @@ source_registry_initable_init (GInitable *initable,
closure->main_loop_mutex);
g_mutex_unlock (closure->main_loop_mutex);
- /* We should now have a GDBusObjectManagerClient available. */
- g_return_val_if_fail (
- G_IS_DBUS_OBJECT_MANAGER_CLIENT (
- registry->priv->dbus_object_manager), FALSE);
+ /* Check for error in the manager thread. */
+ if (closure->error != NULL) {
+ g_propagate_error (error, closure->error);
+ closure->error = NULL;
+ return FALSE;
+ }
/* The registry should now be populated with sources. */
g_warn_if_fail (g_hash_table_size (registry->priv->sources) > 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]