[telepathy-glib/f17] Backport patch that gives features a second chance to be prepared.
Brian Pepple
bpepple at fedoraproject.org
Thu Jun 21 13:52:33 UTC 2012
commit 258eff4db67072db8bbde678f7def05259a08514
Author: Brian Pepple <bpepple at fedoraproject.org>
Date: Thu Jun 21 09:52:23 2012 -0400
Backport patch that gives features a second chance to be prepared.
retry_features.patch | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++
telepathy-glib.spec | 7 +-
2 files changed, 263 insertions(+), 1 deletions(-)
---
diff --git a/retry_features.patch b/retry_features.patch
new file mode 100644
index 0000000..399c776
--- /dev/null
+++ b/retry_features.patch
@@ -0,0 +1,257 @@
+From 5d2f1f6a6b491a9eb05ff0013a258471d59248de Mon Sep 17 00:00:00 2001
+From: Guillaume Desmottes <guillaume.desmottes at collabora.co.uk>
+Date: Wed, 16 Nov 2011 13:23:21 +0000
+Subject: Retry to prepare features which failed because of a missing conn iface
+
+If we try to prepare a connection feature before the connection is connected,
+the preparation may fall if a required interface hasn't been announced yet by
+the CM. So, we give those features a second chance to be prepared when the
+connection has been connected.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=42981
+---
+diff --git a/telepathy-glib/proxy.c b/telepathy-glib/proxy.c
+index 4e8e839..6533877 100644
+--- a/telepathy-glib/proxy.c
++++ b/telepathy-glib/proxy.c
+@@ -323,6 +323,11 @@ typedef enum {
+ FEATURE_STATE_WANTED,
+ /* Want to prepare, have called prepare_async */
+ FEATURE_STATE_TRYING,
++ /* Couldn't prepare because a required interface on the connection
++ * was missing and the connection wasn't connected yet. We'll retry to
++ * prepare once the connection is connected.
++ * This state is only used when preparing Connection features */
++ FEATURE_STATE_MISSING_IFACE,
+ /* Couldn't prepare, gave up */
+ FEATURE_STATE_FAILED,
+ /* Prepared */
+@@ -1789,6 +1794,7 @@ check_depends_ready (TpProxy *self,
+ return FALSE;
+
+ case FEATURE_STATE_FAILED:
++ case FEATURE_STATE_MISSING_IFACE:
+ if (!can_retry || !dep_feature->can_retry)
+ {
+ DEBUG ("Can't prepare %s, because %s (a dependency) is "
+@@ -2089,8 +2095,21 @@ request_is_complete (TpProxy *self,
+ * in tp_proxy_prepare_async() as CORE have to be prepared */
+ if (!check_feature_interfaces (self, feature))
+ {
+- tp_proxy_set_feature_state (self, feature,
+- FEATURE_STATE_FAILED);
++ if (TP_IS_CONNECTION (self) &&
++ tp_connection_get_status ((TpConnection *) self, NULL)
++ != TP_CONNECTION_STATUS_CONNECTED)
++ {
++ /* Give a chance to retry preparing the feature once
++ * the Connection is connected as it may still gain
++ * the interface. */
++ tp_proxy_set_feature_state (self, feature,
++ FEATURE_STATE_MISSING_IFACE);
++ }
++ else
++ {
++ tp_proxy_set_feature_state (self, feature,
++ FEATURE_STATE_FAILED);
++ }
+ continue;
+ }
+
+@@ -2126,6 +2145,7 @@ request_is_complete (TpProxy *self,
+
+ case FEATURE_STATE_INVALID:
+ case FEATURE_STATE_FAILED:
++ case FEATURE_STATE_MISSING_IFACE:
+ case FEATURE_STATE_READY:
+ /* nothing more to do */
+ break;
+@@ -2318,20 +2338,34 @@ static void foreach_feature (GQuark name,
+ {
+ FeatureState state = GPOINTER_TO_INT (data);
+ TpProxy *self = user_data;
+- const TpProxyFeature *feature;
+
+- if (state != FEATURE_STATE_READY)
+- return;
++ if (state == FEATURE_STATE_MISSING_IFACE)
++ {
++ GQuark features[] = { 0, 0};
+
+- feature = tp_proxy_subclass_get_feature (G_OBJECT_TYPE (self), name);
++ tp_proxy_set_feature_state (self, name, FEATURE_STATE_UNWANTED);
+
+- if (feature->prepare_before_signalling_connected_async == NULL)
+- return;
++ self->priv->pending_will_announce_calls++;
+
+- self->priv->pending_will_announce_calls++;
++ features[0] = name;
+
+- feature->prepare_before_signalling_connected_async (self, feature,
+- prepare_before_signalling_connected_cb, self);
++ tp_proxy_prepare_async (self, features,
++ prepare_before_signalling_connected_cb, self);
++ }
++ else if (state == FEATURE_STATE_READY)
++ {
++ const TpProxyFeature *feature;
++
++ feature = tp_proxy_subclass_get_feature (G_OBJECT_TYPE (self), name);
++
++ if (feature->prepare_before_signalling_connected_async == NULL)
++ return;
++
++ self->priv->pending_will_announce_calls++;
++
++ feature->prepare_before_signalling_connected_async (self, feature,
++ prepare_before_signalling_connected_cb, self);
++ }
+ }
+
+ /*
+diff --git a/tests/dbus/proxy-preparation.c b/tests/dbus/proxy-preparation.c
+index df4b1b7..7d7638f 100644
+--- a/tests/dbus/proxy-preparation.c
++++ b/tests/dbus/proxy-preparation.c
+@@ -368,6 +368,43 @@ test_before_connected (Test *test,
+ BEFORE_CONNECTED_STATE_CONNECTED);
+ }
+
++static void
++test_interface_later (Test *test,
++ gconstpointer data G_GNUC_UNUSED)
++{
++ GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER, 0 };
++ GQuark connected[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };
++ const gchar *interfaces[] = { TP_TESTS_MY_CONN_PROXY_IFACE_LATER, NULL };
++
++ /* We need a not yet connected connection */
++ recreate_connection (test);
++
++ /* Try preparing before the connection is connected */
++ tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test);
++
++ g_main_loop_run (test->mainloop);
++ g_assert_no_error (test->error);
++
++ /* Feature isn't prepared */
++ g_assert (!tp_proxy_is_prepared (test->my_conn,
++ TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER));
++
++ tp_cli_connection_call_connect (test->connection, -1, NULL, NULL, NULL, NULL);
++
++ /* While connecting the interface is added */
++ tp_base_connection_add_interfaces (test->base_connection, interfaces);
++
++ /* Wait that CONNECTED is announced */
++ tp_proxy_prepare_async (test->my_conn, connected, prepare_cb, test);
++
++ g_main_loop_run (test->mainloop);
++ g_assert_no_error (test->error);
++
++ /* The feature has been prepared now */
++ g_assert (tp_proxy_is_prepared (test->my_conn,
++ TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER));
++}
++
+ int
+ main (int argc,
+ char **argv)
+@@ -395,6 +432,8 @@ main (int argc,
+ test_retry_dep, teardown);
+ g_test_add ("/proxy-preparation/before-connected", Test, NULL, setup,
+ test_before_connected, teardown);
++ g_test_add ("/proxy-preparation/interface-later", Test, NULL, setup,
++ test_interface_later, teardown);
+
+ return g_test_run ();
+ }
+diff --git a/tests/lib/my-conn-proxy.c b/tests/lib/my-conn-proxy.c
+index 208f004..d7748f3 100644
+--- a/tests/lib/my-conn-proxy.c
++++ b/tests/lib/my-conn-proxy.c
+@@ -33,6 +33,7 @@ enum {
+ FEAT_RETRY,
+ FEAT_RETRY_DEP,
+ FEAT_BEFORE_CONNECTED,
++ FEAT_INTERFACE_LATER,
+ N_FEAT
+ };
+
+@@ -203,6 +204,21 @@ prepare_before_connected_before_async (TpProxy *proxy,
+ g_object_unref (result);
+ }
+
++static void
++prepare_interface_later_async (TpProxy *proxy,
++ const TpProxyFeature *feature,
++ GAsyncReadyCallback callback,
++ gpointer user_data)
++{
++ GSimpleAsyncResult *result;
++
++ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
++ prepare_interface_later_async);
++
++ g_simple_async_result_complete_in_idle (result);
++ g_object_unref (result);
++}
++
+ static const TpProxyFeature *
+ list_features (TpProxyClass *cls G_GNUC_UNUSED)
+ {
+@@ -212,6 +228,7 @@ list_features (TpProxyClass *cls G_GNUC_UNUSED)
+ static GQuark need_wrong_iface[2] = {0, 0};
+ static GQuark need_fail[2] = {0, 0};
+ static GQuark need_retry[2] = {0, 0};
++ static GQuark need_iface_later[2] = {0, 0};
+
+ if (G_LIKELY (features[0].name != 0))
+ return features;
+@@ -262,6 +279,13 @@ list_features (TpProxyClass *cls G_GNUC_UNUSED)
+ features[FEAT_BEFORE_CONNECTED].prepare_before_signalling_connected_async =
+ prepare_before_connected_before_async;
+
++ features[FEAT_INTERFACE_LATER].name =
++ TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER;
++ features[FEAT_INTERFACE_LATER].prepare_async = prepare_interface_later_async;
++ need_iface_later[0] = g_quark_from_static_string (
++ TP_TESTS_MY_CONN_PROXY_IFACE_LATER);
++ features[FEAT_INTERFACE_LATER].interfaces_needed = need_iface_later;
++
+ return features;
+ }
+
+@@ -332,3 +356,9 @@ tp_tests_my_conn_proxy_get_feature_quark_before_connected (void)
+ {
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-before-connected");
+ }
++
++GQuark
++tp_tests_my_conn_proxy_get_feature_quark_interface_later (void)
++{
++ return g_quark_from_static_string ("tp-my-conn-proxy-feature-interface-later");
++}
+diff --git a/tests/lib/my-conn-proxy.h b/tests/lib/my-conn-proxy.h
+index cfc8216..08be18b 100644
+--- a/tests/lib/my-conn-proxy.h
++++ b/tests/lib/my-conn-proxy.h
+@@ -110,6 +110,15 @@ GQuark tp_tests_my_conn_proxy_get_feature_quark_retry_dep (void) G_GNUC_CONST;
+ (tp_tests_my_conn_proxy_get_feature_quark_before_connected ())
+ GQuark tp_tests_my_conn_proxy_get_feature_quark_before_connected (void) G_GNUC_CONST;
+
++#define TP_TESTS_MY_CONN_PROXY_IFACE_LATER "org.freedesktop.Telepathy.Conncetion.Interface.Test.Later"
++
++/* Need the interface TP_TESTS_MY_CONN_PROXY_IFACE_LATER to be prepared but
++ * this interface is not in the initial set of interfaces of the connection.
++ * It is added when the connection is connected. */
++#define TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER \
++ (tp_tests_my_conn_proxy_get_feature_quark_interface_later ())
++GQuark tp_tests_my_conn_proxy_get_feature_quark_interface_later (void) G_GNUC_CONST;
++
+ G_END_DECLS
+
+ #endif /* #ifndef __TP_TESTS_MY_CONN_PROXY_H__ */
+--
+cgit v0.9.0.2-2-gbebe
diff --git a/telepathy-glib.spec b/telepathy-glib.spec
index 822dd27..983ff9e 100644
--- a/telepathy-glib.spec
+++ b/telepathy-glib.spec
@@ -6,13 +6,14 @@
Name: telepathy-glib
Version: 0.18.1
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: GLib bindings for Telepathy
Group: System Environment/Libraries
License: LGPLv2+
URL: http://telepathy.freedesktop.org/wiki/FrontPage
Source0: http://telepathy.freedesktop.org/releases/%{name}/%{name}-%{version}.tar.gz
+Patch0: retry_features.patch
BuildRequires: gtk-doc >= 1.17
BuildRequires: dbus-devel >= %{dbus_ver}
@@ -60,6 +61,7 @@ developing applications that use %{name}.
%prep
%setup -q
+%patch0 -p1 -b .features
%check
@@ -106,6 +108,9 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
%changelog
+* Thu Jun 21 2012 Brian Pepple <bpepple at fedoraproject.org> - 0.18.1-2
+- Backport patch that gives features a second chance to be prepared.
+
* Sat Apr 21 2012 Brian Pepple <bpepple at fedoraproject.org> - 0.18.1-1
- Update to 0.18.1.
More information about the scm-commits
mailing list