#define E_SETTINGS_DEFAULT_MEMO_LIST_KEY "default-memo-list"
#define E_SETTINGS_DEFAULT_TASK_LIST_KEY "default-task-list"
-/* This forces the GType to be registered in a way that
- * avoids a "statement with no effect" compiler warning.
- * FIXME Use g_type_ensure() once we require GLib 2.34. */
-#define REGISTER_TYPE(type) \
- (g_type_class_unref (g_type_class_ref (type)))
-
typedef struct _AsyncContext AsyncContext;
typedef struct _AuthContext AuthContext;
typedef struct _CreateContext CreateContext;
EDBusSourceManager *dbus_source_manager;
GHashTable *object_path_table;
- GMutex *object_path_table_lock;
+ GMutex object_path_table_lock;
GHashTable *sources;
- GMutex *sources_lock;
+ GMutex sources_lock;
GSettings *settings;
};
ESourceRegistry *registry;
GMainContext *main_context;
GMainLoop *main_loop;
- GCond *main_loop_cond;
- GMutex *main_loop_mutex;
+ GCond main_loop_cond;
+ GMutex main_loop_mutex;
GError *error;
};
g_main_context_unref (closure->main_context);
g_main_loop_unref (closure->main_loop);
- g_cond_free (closure->main_loop_cond);
- g_mutex_free (closure->main_loop_mutex);
+ g_cond_clear (&closure->main_loop_cond);
+ g_mutex_clear (&closure->main_loop_mutex);
/* The GError should be NULL at this point,
* regardless of whether an error occurred. */
g_return_if_fail (object_path != NULL);
g_return_if_fail (E_IS_SOURCE (source));
- g_mutex_lock (registry->priv->object_path_table_lock);
+ g_mutex_lock (®istry->priv->object_path_table_lock);
g_hash_table_insert (
registry->priv->object_path_table,
g_strdup (object_path),
g_object_ref (source));
- g_mutex_unlock (registry->priv->object_path_table_lock);
+ g_mutex_unlock (®istry->priv->object_path_table_lock);
}
static ESource *
g_return_val_if_fail (object_path != NULL, NULL);
- g_mutex_lock (registry->priv->object_path_table_lock);
+ g_mutex_lock (®istry->priv->object_path_table_lock);
source = g_hash_table_lookup (
registry->priv->object_path_table, object_path);
if (source != NULL)
g_object_ref (source);
- g_mutex_unlock (registry->priv->object_path_table_lock);
+ g_mutex_unlock (®istry->priv->object_path_table_lock);
return source;
}
g_return_val_if_fail (object_path != NULL, FALSE);
- g_mutex_lock (registry->priv->object_path_table_lock);
+ g_mutex_lock (®istry->priv->object_path_table_lock);
removed = g_hash_table_remove (
registry->priv->object_path_table, object_path);
- g_mutex_unlock (registry->priv->object_path_table_lock);
+ g_mutex_unlock (®istry->priv->object_path_table_lock);
return removed;
}
uid = e_source_get_uid (source);
g_return_if_fail (uid != NULL);
- g_mutex_lock (registry->priv->sources_lock);
+ g_mutex_lock (®istry->priv->sources_lock);
g_hash_table_insert (
registry->priv->sources,
g_strdup (uid), g_object_ref (source));
- g_mutex_unlock (registry->priv->sources_lock);
+ g_mutex_unlock (®istry->priv->sources_lock);
}
static gboolean
uid = e_source_get_uid (source);
g_return_val_if_fail (uid != NULL, FALSE);
- g_mutex_lock (registry->priv->sources_lock);
+ g_mutex_lock (®istry->priv->sources_lock);
removed = g_hash_table_remove (registry->priv->sources, uid);
- g_mutex_unlock (registry->priv->sources_lock);
+ g_mutex_unlock (®istry->priv->sources_lock);
return removed;
}
g_return_val_if_fail (uid != NULL, NULL);
- g_mutex_lock (registry->priv->sources_lock);
+ g_mutex_lock (®istry->priv->sources_lock);
source = g_hash_table_lookup (registry->priv->sources, uid);
if (source != NULL)
g_object_ref (source);
- g_mutex_unlock (registry->priv->sources_lock);
+ g_mutex_unlock (®istry->priv->sources_lock);
return source;
}
{
GList *values;
- g_mutex_lock (registry->priv->sources_lock);
+ g_mutex_lock (®istry->priv->sources_lock);
values = g_hash_table_get_values (registry->priv->sources);
g_list_foreach (values, (GFunc) g_object_ref, NULL);
- g_mutex_unlock (registry->priv->sources_lock);
+ g_mutex_unlock (®istry->priv->sources_lock);
return values;
}
GHashTableIter iter;
gpointer key, value;
- g_mutex_lock (registry->priv->sources_lock);
+ g_mutex_lock (®istry->priv->sources_lock);
root = g_node_new (NULL);
index = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_destroy (index);
- g_mutex_unlock (registry->priv->sources_lock);
+ g_mutex_unlock (®istry->priv->sources_lock);
return root;
}
uid = e_source_get_uid (source);
g_return_if_fail (uid != NULL);
- g_mutex_lock (registry->priv->sources_lock);
+ g_mutex_lock (®istry->priv->sources_lock);
/* Check if we already have this source in the registry. */
if (g_hash_table_lookup (registry->priv->sources, uid) != NULL) {
- g_mutex_unlock (registry->priv->sources_lock);
+ g_mutex_unlock (®istry->priv->sources_lock);
return;
}
G_CALLBACK (source_registry_source_notify_enabled_cb),
registry);
- g_mutex_unlock (registry->priv->sources_lock);
+ g_mutex_unlock (®istry->priv->sources_lock);
source_registry_sources_insert (registry, source);
}
{
ThreadClosure *closure = data;
- g_mutex_lock (closure->main_loop_mutex);
- g_cond_broadcast (closure->main_loop_cond);
- g_mutex_unlock (closure->main_loop_mutex);
+ g_mutex_lock (&closure->main_loop_mutex);
+ g_cond_broadcast (&closure->main_loop_cond);
+ g_mutex_unlock (&closure->main_loop_mutex);
return FALSE;
}
g_hash_table_remove_all (priv->sources);
if (priv->settings != NULL) {
+ g_signal_handlers_disconnect_by_data (priv->settings, object);
g_object_unref (priv->settings);
priv->settings = NULL;
}
priv = E_SOURCE_REGISTRY_GET_PRIVATE (object);
g_hash_table_destroy (priv->object_path_table);
- g_mutex_free (priv->object_path_table_lock);
+ g_mutex_clear (&priv->object_path_table_lock);
g_hash_table_destroy (priv->sources);
- g_mutex_free (priv->sources_lock);
+ g_mutex_clear (&priv->sources_lock);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_source_registry_parent_class)->finalize (object);
* we wait for the main loop to start running as a way of
* synchronizing with the manager thread. */
closure->main_loop = g_main_loop_new (closure->main_context, FALSE);
- closure->main_loop_cond = g_cond_new ();
- closure->main_loop_mutex = g_mutex_new ();
+ g_cond_init (&closure->main_loop_cond);
+ g_mutex_init (&closure->main_loop_mutex);
registry->priv->thread_closure = closure;
- registry->priv->manager_thread = g_thread_create (
+ registry->priv->manager_thread = g_thread_new (
+ NULL,
source_registry_object_manager_thread,
- closure, TRUE /* joinable */, error);
+ closure);
if (registry->priv->manager_thread == NULL)
return FALSE;
/* Wait for notification that the manager
* thread's main loop has been started. */
- g_mutex_lock (closure->main_loop_mutex);
+ g_mutex_lock (&closure->main_loop_mutex);
while (!g_main_loop_is_running (closure->main_loop))
g_cond_wait (
- closure->main_loop_cond,
- closure->main_loop_mutex);
- g_mutex_unlock (closure->main_loop_mutex);
+ &closure->main_loop_cond,
+ &closure->main_loop_mutex);
+ g_mutex_unlock (&closure->main_loop_mutex);
/* Check for error in the manager thread. */
if (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);
+ /* The registry should now be populated with sources.
+ *
+ * XXX Actually, not necessarily if the registry service was
+ * just now activated. There may yet be a small window
+ * while the registry service starts up before it exports
+ * any sources, even built-in sources. This COULD create
+ * problems if any logic that depends on those built-in
+ * sources executes during this time window, but so far
+ * we haven't seen any cases of that.
+ *
+ * Attempts in the past to stop and wait for sources to
+ * show up have proven problematic. See for example:
+ * https://bugzilla.gnome.org/678378
+ *
+ * Leave the runtime check disabled for the moment.
+ * I have a feeling I'll be revisiting this again.
+ */
+ /*g_warn_if_fail (g_hash_table_size (registry->priv->sources) > 0);*/
/* The EDBusSourceManagerProxy is just another D-Bus interface
* that resides at the same object path. It's unrelated to the
(GDestroyNotify) g_free,
(GDestroyNotify) g_object_unref);
- registry->priv->object_path_table_lock = g_mutex_new ();
+ g_mutex_init (®istry->priv->object_path_table_lock);
/* UID string -> ESource */
registry->priv->sources = g_hash_table_new_full (
(GDestroyNotify) g_free,
(GDestroyNotify) source_registry_unref_source);
- registry->priv->sources_lock = g_mutex_new ();
+ g_mutex_init (®istry->priv->sources_lock);
registry->priv->settings = g_settings_new (GSETTINGS_SCHEMA);
/* XXX Work around http://bugzilla.gnome.org/show_bug.cgi?id=683519
* until GObject's type initialization deadlock issue is fixed.
* Apparently only the synchronous instantiation is affected. */
- REGISTER_TYPE (G_TYPE_DBUS_CONNECTION);
+ g_type_ensure (G_TYPE_DBUS_CONNECTION);
return g_initable_new (
E_TYPE_SOURCE_REGISTRY,
exit:
g_main_context_pop_thread_default (main_context);
+
+ /* Make sure the main_context doesn't have pending operations;
+ workarounds https://bugzilla.gnome.org/show_bug.cgi?id=690126 */
+ while (g_main_context_pending (main_context))
+ g_main_context_iteration (main_context, FALSE);
+
g_main_context_unref (main_context);
return success;
uid = E_SOURCE_BUILTIN_ADDRESS_BOOK_UID;
source = e_source_registry_ref_source (registry, uid);
- g_return_val_if_fail (source != NULL, NULL);
return source;
}
source = e_source_registry_ref_source (registry, uid);
g_free (uid);
- /* The built-in source is always present. */
+ /* The built-in source is present in normal EDS installations. */
if (source == NULL)
source = e_source_registry_ref_builtin_address_book (registry);
- g_return_val_if_fail (E_IS_SOURCE (source), NULL);
-
return source;
}
uid = E_SOURCE_BUILTIN_CALENDAR_UID;
source = e_source_registry_ref_source (registry, uid);
- g_return_val_if_fail (source != NULL, NULL);
return source;
}
source = e_source_registry_ref_source (registry, uid);
g_free (uid);
- /* The built-in source is always present. */
+ /* The built-in source is present in normal EDS installations. */
if (source == NULL)
source = e_source_registry_ref_builtin_calendar (registry);
- g_return_val_if_fail (E_IS_SOURCE (source), NULL);
-
return source;
}