[Telepathy-commits] [telepathy-gabble/master] muc-factory: announce tube channels
Guillaume Desmottes
guillaume.desmottes at collabora.co.uk
Mon Jan 19 03:00:25 PST 2009
---
src/muc-factory.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 96 insertions(+), 2 deletions(-)
diff --git a/src/muc-factory.c b/src/muc-factory.c
index cb63cc2..38bd429 100644
--- a/src/muc-factory.c
+++ b/src/muc-factory.c
@@ -77,6 +77,10 @@ struct _GabbleMucFactoryPrivate
* text channel is created.
* Borrowed GabbleMucChannel => borrowed GabbleTubesChannel */
GHashTable *text_needed_for_tubes;
+ /* Tube channels which will be considered ready when the corresponding
+ * tubes channel is created.
+ * Borrowed GabbleTubesChannel => GSlist of borrowed GabbleTubeIface */
+ GHashTable *tubes_needed_for_tube;
/* GabbleDiscoRequest * => NULL (used as a set) */
GHashTable *disco_requests;
@@ -106,6 +110,8 @@ gabble_muc_factory_init (GabbleMucFactory *fac)
NULL, g_object_unref);
priv->text_needed_for_tubes = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, NULL);
+ priv->tubes_needed_for_tube = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal, NULL, (GDestroyNotify) g_slist_free);
priv->disco_requests = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, NULL);
@@ -150,6 +156,7 @@ gabble_muc_factory_dispose (GObject *object)
g_assert (priv->text_channels == NULL);
g_assert (priv->tubes_channels == NULL);
g_assert (priv->text_needed_for_tubes == NULL);
+ g_assert (priv->tubes_needed_for_tube == NULL);
g_assert (priv->queued_requests == NULL);
g_hash_table_foreach (priv->disco_requests, cancel_disco_request,
@@ -294,6 +301,7 @@ muc_ready_cb (GabbleMucChannel *text_chan,
GabbleTubesChannel *tubes_chan;
GSList *requests_satisfied_text, *requests_satisfied_tubes = NULL;
gboolean text_requested;
+ GSList *tube_channels, *l;
DEBUG ("text chan=%p", text_chan);
@@ -344,7 +352,30 @@ muc_ready_cb (GabbleMucChannel *text_chan,
g_hash_table_destroy (channels);
}
+ /* Announce tube channels now */
+ /* FIXME: we should probably aggregate tube announcement with tubes and text
+ * ones in some cases. */
+ tube_channels = g_hash_table_lookup (priv->tubes_needed_for_tube,
+ tubes_chan);
+ tube_channels = g_slist_reverse (tube_channels);
+ for (l = tube_channels; l != NULL; l = g_slist_next (l))
+ {
+ GabbleTubeIface *tube_chan = GABBLE_TUBE_IFACE (l->data);
+ GSList *requests_satisfied_tube;
+
+ requests_satisfied_tube = g_hash_table_lookup (priv->queued_requests,
+ tube_chan);
+ g_hash_table_steal (priv->queued_requests, tube_chan);
+ requests_satisfied_tube = g_slist_reverse (requests_satisfied_tube);
+
+ tp_channel_manager_emit_new_channel (fac,
+ TP_EXPORTABLE_CHANNEL (tube_chan), requests_satisfied_tube);
+
+ g_slist_free (requests_satisfied_tube);
+ }
+
+ g_hash_table_remove (priv->tubes_needed_for_tube, tubes_chan);
g_slist_free (requests_satisfied_text);
g_slist_free (requests_satisfied_tubes);
}
@@ -1106,6 +1137,12 @@ gabble_muc_factory_close_all (GabbleMucFactory *self)
priv->text_needed_for_tubes = NULL;
}
+ if (priv->tubes_needed_for_tube != NULL)
+ {
+ g_hash_table_destroy (priv->tubes_needed_for_tube);
+ priv->tubes_needed_for_tube = NULL;
+ }
+
/* Use a temporary variable because we don't want
* muc_channel_closed_cb or tubes_channel_closed_cb to remove the channel
* from the hash table a second time */
@@ -1482,6 +1519,8 @@ gabble_muc_factory_request (GabbleMucFactory *self,
else if (!tp_strdiff (channel_type, GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE))
{
const gchar *service;
+ gboolean can_announce_now = TRUE;
+ GabbleTubeIface *new_channel;
if (tp_channel_manager_asv_has_unknown_properties (request_properties,
muc_tubes_channel_fixed_properties,
@@ -1505,10 +1544,65 @@ gabble_muc_factory_request (GabbleMucFactory *self,
if (tubes_chan == NULL)
{
/* Need to create a tubes channel */
- /* TODO */
+ if (ensure_tubes_channel (self, handle, &tubes_chan))
+ {
+ GSList *list = NULL;
+
+ /* announce the newly create tubes channel right away */
+ list = g_slist_prepend (list, request_token);
+ tp_channel_manager_emit_new_channel (self,
+ TP_EXPORTABLE_CHANNEL (tubes_chan), list);
+ g_slist_free (list);
+ }
+ else
+ {
+ /* We have to wait the tubes channel before announcing */
+ can_announce_now = FALSE;
+
+ gabble_muc_factory_associate_request (self, tubes_chan,
+ request_token);
+ }
}
- return FALSE;
+ g_assert (tubes_chan != NULL);
+
+ new_channel = gabble_tubes_channel_tube_request (tubes_chan,
+ request_token, request_properties, TRUE);
+ g_assert (new_channel != NULL);
+
+ if (can_announce_now)
+ {
+ GHashTable *channels;
+ GSList *request_tokens;
+
+ channels = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, NULL);
+
+ /* FIXME: announce tubes if needed */
+ /*
+ if (!tubes_channel_already_existed)
+ g_hash_table_insert (channels, channel, NULL);
+ */
+
+ request_tokens = g_slist_prepend (NULL, request_token);
+
+ g_hash_table_insert (channels, new_channel, request_tokens);
+ tp_channel_manager_emit_new_channels (self, channels);
+
+ g_hash_table_destroy (channels);
+ g_slist_free (request_tokens);
+ }
+ else
+ {
+ GSList *l;
+
+ l = g_hash_table_lookup (priv->tubes_needed_for_tube, tubes_chan);
+ g_hash_table_steal (priv->tubes_needed_for_tube, tubes_chan);
+
+ l = g_slist_prepend (l, new_channel);
+ g_hash_table_insert (priv->tubes_needed_for_tube, tubes_chan, l);
+ }
+ return TRUE;
}
error:
--
1.5.6.5
More information about the Telepathy-commits
mailing list