summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--TelepathyQt4/dbus-proxy-factory.cpp18
2 files changed, 20 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 323d431e..560d869b 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ Enhancements:
Fixes:
* Properly install TelepathyQt4/ConnectionManagerLowLevel.
+ * A race condition causing proxies to be needlessly dropped from the factory
+ cache and hence new proxies built for a future request.
telepathy-qt4 0.5.1 (2010-12-08)
=================================
diff --git a/TelepathyQt4/dbus-proxy-factory.cpp b/TelepathyQt4/dbus-proxy-factory.cpp
index 4554f9a3..5a0e94f5 100644
--- a/TelepathyQt4/dbus-proxy-factory.cpp
+++ b/TelepathyQt4/dbus-proxy-factory.cpp
@@ -248,6 +248,24 @@ void DBusProxyFactory::Cache::put(const DBusProxyPtr &proxy)
DBusProxyPtr existingProxy(proxies.value(key));
if (!existingProxy || existingProxy != proxy) {
+ // Disconnect the invalidated signal from the proxy we're replacing, so it won't uselessly
+ // cause the new (hopefully valid) proxy to be dropped from the cache if it arrives late.
+ //
+ // The window in which this makes a difference is very slim but existent; namely, somebody
+ // must request a proxy from the factory in the same mainloop iteration as an otherwise
+ // matching proxy has invalidated itself. The invalidation signal would be delivered and
+ // processed only during the next mainloop iteration.
+ if (existingProxy) {
+ Q_ASSERT(!existingProxy->isValid());
+ existingProxy->disconnect(
+ SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
+ this,
+ SLOT(onProxyInvalidated(Tp::DBusProxy*)));
+
+ debug() << "Replacing invalidated proxy" << existingProxy.data() << "in cache for name"
+ << existingProxy->busName() << ',' << existingProxy->objectPath();
+ }
+
connect(proxy.data(),
SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
SLOT(onProxyInvalidated(Tp::DBusProxy*)));