From 42612cdf772bc6a03d2f43bbbc3568d1439227c2 Mon Sep 17 00:00:00 2001 From: Travis Reitter Date: Thu, 9 Sep 2010 09:24:11 -0700 Subject: [PATCH] Add Backend.is_prepared and make prepare() idempotent. Fixes bgo#629331. --- NEWS | 3 ++ backends/key-file/kf-backend.vala | 66 ++++++++++++++++++++++++++------------ backends/telepathy/tp-backend.vala | 47 ++++++++++++++++++++------- folks/backend.vala | 10 ++++++ 4 files changed, 95 insertions(+), 31 deletions(-) diff --git a/NEWS b/NEWS index bb31260..4986937 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ Major changes: * Made the folks-import build optional through a configure argument * Added support for a “self” individual * Added support for generating and installing Devhelp format documentation +* BackendStore.load_backends and the prepare() functions are now idempotent API changes: * Added IMable.normalise_im_address() @@ -42,6 +43,8 @@ Bugs fixed: * Bug 629643 — do not fall back to the id if alias is empty * Bug 629006 — PersonaStore should gracefully handle offline Persona change attempts +* Bug 629331 — BackendStore.load_backends and the prepare() functions should + be idempotent. Overview of changes from libfolks 0.1.16 to libfolks 0.1.17 =========================================================== diff --git a/backends/key-file/kf-backend.vala b/backends/key-file/kf-backend.vala index 3da0d23..b36c4f4 100644 --- a/backends/key-file/kf-backend.vala +++ b/backends/key-file/kf-backend.vala @@ -31,6 +31,20 @@ using Folks.Backends.Kf; */ public class Folks.Backends.Kf.Backend : Folks.Backend { + private bool _is_prepared = false; + + /** + * Whether this Backend has been prepared. + * + * See {@link Folks.Backend.is_prepared}. + * + * @since 0.3.0 + */ + public override bool is_prepared + { + get { return this._is_prepared; } + } + /** * {@inheritDoc} */ @@ -57,31 +71,43 @@ public class Folks.Backends.Kf.Backend : Folks.Backend */ public override async void prepare () throws GLib.Error { - File file; - string path = Environment.get_variable ("FOLKS_BACKEND_KEY_FILE_PATH"); - if (path == null) + lock (this._is_prepared) { - file = File.new_for_path (Environment.get_user_data_dir ()); - file = file.get_child ("folks"); - file = file.get_child ("relationships.ini"); + if (!this._is_prepared) + { + File file; + string path = Environment.get_variable ( + "FOLKS_BACKEND_KEY_FILE_PATH"); + if (path == null) + { + file = File.new_for_path (Environment.get_user_data_dir ()); + file = file.get_child ("folks"); + file = file.get_child ("relationships.ini"); - debug ("Using built-in key file '%s' (override with environment " + - "variable FOLKS_BACKEND_KEY_FILE_PATH)", file.get_path ()); - } - else - { - file = File.new_for_path (path); - debug ("Using environment variable FOLKS_BACKEND_KEY_FILE_PATH = '%s'" - + " to load the key file.", path); - } + debug ("Using built-in key file '%s' (override with " + + "environment variable FOLKS_BACKEND_KEY_FILE_PATH)", + file.get_path ()); + } + else + { + file = File.new_for_path (path); + debug ("Using environment variable " + + "FOLKS_BACKEND_KEY_FILE_PATH = '%s' to load the key " + + "file.", path); + } - /* Create the PersonaStore for the key file */ - PersonaStore store = new Kf.PersonaStore (file); + /* Create the PersonaStore for the key file */ + PersonaStore store = new Kf.PersonaStore (file); - this.persona_stores.insert (store.id, store); - store.removed.connect (this.store_removed_cb); + this.persona_stores.insert (store.id, store); + store.removed.connect (this.store_removed_cb); - this.persona_store_added (store); + this.persona_store_added (store); + + this._is_prepared = true; + this.notify_property ("is-prepared"); + } + } } private void store_removed_cb (Folks.PersonaStore store) diff --git a/backends/telepathy/tp-backend.vala b/backends/telepathy/tp-backend.vala index d1536f8..edc8df8 100644 --- a/backends/telepathy/tp-backend.vala +++ b/backends/telepathy/tp-backend.vala @@ -30,6 +30,7 @@ using Folks.Backends.Tp; public class Folks.Backends.Tp.Backend : Folks.Backend { private AccountManager account_manager; + private bool _is_prepared = false; /** * {@inheritDoc} @@ -53,23 +54,47 @@ public class Folks.Backends.Tp.Backend : Folks.Backend } /** + * Whether this Backend has been prepared. + * + * See {@link Folks.Backend.is_prepared}. + * + * @since 0.3.0 + */ + public override bool is_prepared + { + get { return this._is_prepared; } + } + + /** * {@inheritDoc} */ public override async void prepare () throws GLib.Error { - this.account_manager = AccountManager.dup (); - yield this.account_manager.prepare_async (null); - this.account_manager.account_enabled.connect (this.account_enabled_cb); - this.account_manager.account_validity_changed.connect ((a, valid) => + lock (this._is_prepared) { - if (valid) - this.account_enabled_cb (a); - }); + if (!this._is_prepared) + { + this.account_manager = AccountManager.dup (); + yield this.account_manager.prepare_async (null); + this.account_manager.account_enabled.connect ( + this.account_enabled_cb); + this.account_manager.account_validity_changed.connect ( + (a, valid) => + { + if (valid) + this.account_enabled_cb (a); + }); - GLib.List accounts = this.account_manager.get_valid_accounts (); - foreach (Account account in accounts) - { - this.account_enabled_cb (account); + GLib.List accounts = + this.account_manager.get_valid_accounts (); + foreach (Account account in accounts) + { + this.account_enabled_cb (account); + } + + this._is_prepared = true; + this.notify_property ("is-prepared"); + } } } diff --git a/folks/backend.vala b/folks/backend.vala index 5565b48..696a00c 100644 --- a/folks/backend.vala +++ b/folks/backend.vala @@ -35,6 +35,14 @@ using GLib; public abstract class Folks.Backend : Object { /** + * Whether {@link Backend.prepare} has successfully completed for this + * backend. + * + * @since 0.3.0 + */ + public abstract bool is_prepared { get; default = false; } + + /** * A unique name for the backend. * * This will be used to identify the backend, and should also be used as the @@ -91,6 +99,8 @@ public abstract class Folks.Backend : Object * * If this function throws an error, the Backend will not be functional. * + * This function is guaranteed to be idempotent (since version 0.3.0). + * * @since 0.1.11 */ public abstract async void prepare () throws GLib.Error; -- 2.7.4