diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2011-01-17 14:19:54 +0100 |
---|---|---|
committer | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2011-05-12 12:30:41 +0200 |
commit | 343e602c8ad7d9550265b4793f63cc2427c8419a (patch) | |
tree | ca2bc10ad0a1ca95bd5b8636aecf76c545c19059 | |
parent | 6d7f23df8ea606f36a731de58e9591b6be079b61 (diff) |
split prepare_core into one TpProxyPrepareRequest per subclass
We'll need this to guarantee that super class core features are prepared
before subclass ones.
-rw-r--r-- | telepathy-glib/proxy.c | 79 |
1 files changed, 44 insertions, 35 deletions
diff --git a/telepathy-glib/proxy.c b/telepathy-glib/proxy.c index fc24987e..ab798599 100644 --- a/telepathy-glib/proxy.c +++ b/telepathy-glib/proxy.c @@ -303,6 +303,7 @@ typedef enum { typedef struct { GSimpleAsyncResult *result; GArray *features; + gboolean core; } TpProxyPrepareRequest; static TpProxyPrepareRequest * @@ -347,12 +348,11 @@ struct _TpProxyPrivate { /* feature => FeatureState */ GData *features; - /* List of TpProxyPrepareRequest */ + /* List of TpProxyPrepareRequest. The first requests are the core one, + * sorted from the most upper super class to the subclass core features. + * This is needed to guarantee than subclass features are not prepared + * until the super class features have been prepared. */ GList *prepare_requests; - /* A request containing all core features, borrowed from the head of - * prepare_requests, or NULL if prepared; nothing else is allowed - * to become prepared until this one does.*/ - TpProxyPrepareRequest *prepare_core; gboolean dispose_has_run; }; @@ -965,12 +965,9 @@ tp_proxy_constructor (GType type, TpProxyInterfaceAddLink *iter; GType proxy_parent_type = G_TYPE_FROM_CLASS (tp_proxy_parent_class); GType ancestor_type; - GArray *core_features; _tp_register_dbus_glib_marshallers (); - core_features = g_array_new (TRUE, FALSE, sizeof (GQuark)); - for (ancestor_type = type; ancestor_type != proxy_parent_type && ancestor_type != 0; ancestor_type = g_type_parent (ancestor_type)) @@ -978,6 +975,7 @@ tp_proxy_constructor (GType type, TpProxyClass *ancestor = g_type_class_peek (ancestor_type); const TpProxyFeature *features; guint i; + GArray *core_features; for (iter = g_type_get_qdata (ancestor_type, interface_added_cb_quark ()); @@ -994,6 +992,8 @@ tp_proxy_constructor (GType type, if (features == NULL) continue; + core_features = g_array_new (TRUE, FALSE, sizeof (GQuark)); + for (i = 0; features[i].name != 0; i++) { tp_proxy_set_feature_state (self, features[i].name, @@ -1004,6 +1004,23 @@ tp_proxy_constructor (GType type, g_array_append_val (core_features, features[i].name); } } + + if (core_features->len > 0) + { + TpProxyPrepareRequest *req; + + req = tp_proxy_prepare_request_new (NULL, + (const GQuark *) core_features->data); + req->core = TRUE; + + self->priv->prepare_requests = g_list_prepend ( + self->priv->prepare_requests, req); + + DEBUG ("%p: request %p represents core features on %s", self, req, + g_type_name (ancestor_type)); + } + + g_array_free (core_features, TRUE); } g_return_val_if_fail (self->dbus_connection != NULL, NULL); @@ -1031,19 +1048,6 @@ tp_proxy_constructor (GType type, g_return_val_if_fail (self->bus_name[0] == ':', NULL); } - if (core_features->len > 0) - { - self->priv->prepare_core = tp_proxy_prepare_request_new (NULL, - (const GQuark *) core_features->data); - self->priv->prepare_requests = g_list_prepend ( - self->priv->prepare_requests, - self->priv->prepare_core); - DEBUG ("%p: request %p represents core features", self, - self->priv->prepare_core); - } - - g_array_free (core_features, TRUE); - return (GObject *) self; } @@ -1084,7 +1088,6 @@ tp_proxy_finalize (GObject *object) /* invalidation ensures that these have gone away */ g_assert (self->priv->prepare_requests == NULL); - g_assert (self->priv->prepare_core == NULL); g_free (self->bus_name); g_free (self->object_path); @@ -1903,6 +1906,19 @@ prepare_feature (TpProxy *self, (gpointer) feature); } +static gboolean +core_prepared (TpProxy *self) +{ + /* All the core features have been prepared if the head of the + * prepare_requests list is NOT a core feature */ + TpProxyPrepareRequest *req = self->priv->prepare_requests->data; + + if (req == NULL) + return TRUE; + + return !req->core; +} + /* Returns %TRUE if all the features requested in @req have complete their * preparation */ static gboolean @@ -1924,13 +1940,13 @@ request_is_complete (TpProxy *self, case FEATURE_STATE_UNWANTED: /* this can only happen in the special pseudo-request for the * core features, which blocks everything */ - g_assert (req == self->priv->prepare_core); + g_assert (req->core); complete = FALSE; /* fall through to treat it as WANTED */ case FEATURE_STATE_WANTED: - if (self->priv->prepare_core == NULL || - self->priv->prepare_core == req) + if (core_prepared (self) || + req->core) { gboolean failed; @@ -2027,7 +2043,6 @@ tp_proxy_poll_features (TpProxy *self, { DEBUG ("%p: %s, ending all requests", self, error_source); iter = self->priv->prepare_requests; - self->priv->prepare_core = NULL; self->priv->prepare_requests = NULL; for ( ; iter != NULL; iter = g_list_delete_link (iter, iter)) @@ -2040,9 +2055,9 @@ tp_proxy_poll_features (TpProxy *self, next = iter->next; - /* prepare_core is always the first in the list (if present), so it - * will always have been checked by the time we reach any later one */ - if (self->priv->prepare_core != NULL && req != self->priv->prepare_core) + /* Core features have to be prepared first */ + if (!core_prepared (self) && + !req->core) { DEBUG ("%p: core features not ready yet, nothing prepared", self); continue; @@ -2054,12 +2069,6 @@ tp_proxy_poll_features (TpProxy *self, self->priv->prepare_requests = g_list_delete_link ( self->priv->prepare_requests, iter); - if (req == self->priv->prepare_core) - { - DEBUG ("%p: core features ready", self); - self->priv->prepare_core = NULL; - } - tp_proxy_prepare_request_finish (req, NULL); } } |