[folks] telepathy: Yield subsequent Logger.prepare() calls if one is pending
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] telepathy: Yield subsequent Logger.prepare() calls if one is pending
- Date: Fri, 28 Dec 2012 14:00:35 +0000 (UTC)
commit ce55fa2bf2f5f8cf95532da585d835bafeeb3347
Author: Philip Withnall <philip tecnocode co uk>
Date: Fri Dec 28 13:47:50 2012 +0000
telepathy: Yield subsequent Logger.prepare() calls if one is pending
If one PersonaStore began to prepare its Logger, then yielded on a D-Bus
call, another PersonaStore could begin to prepare its Logger and also
try to create a static D-Bus proxy (which is only supposed to be created
once). This is because the original async call hasnât returned and set
Logger._logger by that point.
Fix this by keeping a queue of pending prepare() calls which is signalled
by the initial prepare() call once it finishes yielding.
Closes: https://bugzilla.gnome.org/show_bug.cgi?id=677633
NEWS | 1 +
backends/telepathy/lib/tpf-logger.vala | 47 +++++++++++++++++++++++++++----
2 files changed, 42 insertions(+), 6 deletions(-)
---
diff --git a/NEWS b/NEWS
index 108ea74..15f0f76 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,7 @@ Bugs fixed:
â Bug 688923 â remove URLs (blog, free/busy, video, home page)
â Bug 689146 â disabling EDS address books does not remove personas
â Bug 689859 â core folks does not depend on telepathy
+â Bug 677633 â Cannot delete favourite
API changes:
â Add Backend.enable_persona_store and disable_persona_store.
diff --git a/backends/telepathy/lib/tpf-logger.vala b/backends/telepathy/lib/tpf-logger.vala
index 5489f9b..2dccb67 100644
--- a/backends/telepathy/lib/tpf-logger.vala
+++ b/backends/telepathy/lib/tpf-logger.vala
@@ -43,10 +43,19 @@ private interface LoggerIface : Object
ObjectPath account_path, string[] added, string[] removed);
}
+/* See: https://mail.gnome.org/archives/vala-list/2011-June/msg00008.html */
+[Compact]
+private class DelegateWrapper
+{
+ public SourceFunc cb;
+}
+
internal class Logger : GLib.Object
{
private static DBusConnection _dbus_conn;
private static LoggerIface _logger;
+ private static DelegateWrapper[] _prepare_waiters = null;
+
private uint _logger_watch_id;
public signal void invalidated ();
@@ -77,22 +86,48 @@ internal class Logger : GLib.Object
public async void prepare () throws GLib.Error
{
- if (Logger._logger == null)
+ if (Logger._logger == null && Logger._prepare_waiters == null)
{
+ /* If this is the first call to prepare(), start some async calls. We
+ * then yield to the main thread. Any subsequent calls to prepare()
+ * will have their continuations added to the _prepare_waiters list,
+ * and will be signalled once the first call returns.
+ * See: https://bugzilla.gnome.org/show_bug.cgi?id=677633 */
+ Logger._prepare_waiters = new DelegateWrapper[0];
+
/* Create a logger proxy for favourites support */
var dbus_conn = yield Bus.get (BusType.SESSION);
Logger._logger = yield dbus_conn.get_proxy<LoggerIface> (
"org.freedesktop.Telepathy.Logger",
"/org/freedesktop/Telepathy/Logger");
- /* Failure? */
- if (Logger._logger == null)
+ if (Logger._logger != null)
{
- this.invalidated ();
- return;
+ Logger._dbus_conn = dbus_conn;
}
- Logger._dbus_conn = dbus_conn;
+ /* Wake up any waiters. */
+ foreach (unowned DelegateWrapper wrapper in Logger._prepare_waiters)
+ {
+ wrapper.cb ();
+ }
+
+ Logger._prepare_waiters = null;
+ }
+ else if (Logger._logger == null && Logger._prepare_waiters != null)
+ {
+ /* Yield until the first ongoing prepare() call finishes. */
+ var wrapper = new DelegateWrapper ();
+ wrapper.cb = prepare.callback;
+ Logger._prepare_waiters += (owned) wrapper;
+ yield;
+ }
+
+ /* Failure? */
+ if (Logger._logger == null)
+ {
+ this.invalidated ();
+ return;
}
this._logger_watch_id = Bus.watch_name_on_connection (Logger._dbus_conn,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]