diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2012-03-28 14:53:43 +0100 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2012-03-28 14:58:12 +0100 |
commit | 44582af04f111e4ba855afceb814997fce812a4e (patch) | |
tree | af1e71b6a7203c0b37a3fb30fa8a931c2acf1dea | |
parent | b8f84c653318b18c5070085e66fca011f04bcb65 (diff) |
bytestream-ibb: handle IQ send errors
This is untested, but the existing tests still pass…
https://bugs.freedesktop.org/show_bug.cgi?id=47999
-rw-r--r-- | src/bytestream-ibb.c | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/src/bytestream-ibb.c b/src/bytestream-ibb.c index de8bfbf51..bfa1b5641 100644 --- a/src/bytestream-ibb.c +++ b/src/bytestream-ibb.c @@ -32,6 +32,7 @@ #include "bytestream-factory.h" #include "bytestream-iface.h" #include "connection.h" +#include "conn-util.h" #include "debug.h" #include "disco.h" #include "namespaces.h" @@ -402,29 +403,46 @@ send_close_stanza (GabbleBytestreamIBB *self) } static guint -send_data (GabbleBytestreamIBB *self, const gchar *str, guint len, - gboolean *result); +send_data (GabbleBytestreamIBB *self, const gchar *str, guint len); static void -iq_acked_cb (GabbleConnection *conn, - WockyStanza *sent_msg, - WockyStanza *reply_msg, - GObject *obj, - gpointer user_data) +iq_reply_cb ( + GObject *source, + GAsyncResult *result, + gpointer user_data) { - GabbleBytestreamIBB *self = GABBLE_BYTESTREAM_IBB (obj); - GabbleBytestreamIBBPrivate *priv = GABBLE_BYTESTREAM_IBB_GET_PRIVATE (self); + TpWeakRef *weak_ref = user_data; + GabbleBytestreamIBB *self = tp_weak_ref_dup_object (weak_ref); + /* We don't hold a ref to the outgoing stanza; we just use its address as a + * key */ + gpointer sent_msg = tp_weak_ref_get_user_data (weak_ref); + GabbleBytestreamIBBPrivate *priv; + GError *error = NULL; + + tp_weak_ref_destroy (weak_ref); + /* If the channel is already dead, never mind! */ + if (self == NULL) + return; + + priv = GABBLE_BYTESTREAM_IBB_GET_PRIVATE (self); g_hash_table_remove (priv->sent_stanzas_not_acked, sent_msg); - if (priv->write_buffer != NULL) + if (!conn_util_send_iq_finish (GABBLE_CONNECTION (source), result, NULL, &error)) + { + DEBUG ("error sending IBB stanza: %s #%u '%s'. Closing the bytestream", + g_quark_to_string (error->domain), error->code, error->message); + g_clear_error (&error); + /* FIXME: we should be able to feed this up to the application somehow. */ + gabble_bytestream_iface_close (GABBLE_BYTESTREAM_IFACE (self), NULL); + } + else if (priv->write_buffer != NULL) { guint sent; DEBUG ("A stanza has been acked. Try to flush the buffer"); - sent = send_data (self, priv->write_buffer->str, priv->write_buffer->len, - NULL); + sent = send_data (self, priv->write_buffer->str, priv->write_buffer->len); if (sent == priv->write_buffer->len) { DEBUG ("buffer has been flushed; unblock write the bytestream"); @@ -450,13 +468,14 @@ iq_acked_cb (GabbleConnection *conn, priv->write_buffer->len); } } + + g_object_unref (self); } static guint send_data (GabbleBytestreamIBB *self, const gchar *str, - guint len, - gboolean *result) + guint len) { GabbleBytestreamIBBPrivate *priv = GABBLE_BYTESTREAM_IBB_GET_PRIVATE (self); guint sent, stanza_count; @@ -468,8 +487,6 @@ send_data (GabbleBytestreamIBB *self, WockyStanza *iq; guint send_now, remaining; gchar *seq, *encoded; - GError *error = NULL; - gboolean ret; guint nb_stanzas_waiting; remaining = (len - sent); @@ -506,27 +523,13 @@ send_data (GabbleBytestreamIBB *self, '@', "seq", seq, ')', NULL); - ret = _gabble_connection_send_with_reply (priv->conn, iq, iq_acked_cb, - G_OBJECT (self), NULL, &error); + conn_util_send_iq_async (priv->conn, iq, NULL, + iq_reply_cb, tp_weak_ref_new (self, iq, NULL)); g_free (encoded); g_free (seq); g_object_unref (iq); - if (!ret) - { - DEBUG ("error sending IBB stanza: %s. Close the bytestream", - error->message); - g_error_free (error); - - gabble_bytestream_iface_close (GABBLE_BYTESTREAM_IFACE (self), NULL); - - if (result != NULL) - *result = FALSE; - - return sent; - } - g_hash_table_insert (priv->sent_stanzas_not_acked, iq, GUINT_TO_POINTER (TRUE)); @@ -539,8 +542,6 @@ send_data (GabbleBytestreamIBB *self, DEBUG ("sent %d bytes (%d stanzas needed)", sent, stanza_count); - if (result != NULL) - *result = TRUE; return sent; } @@ -556,7 +557,6 @@ gabble_bytestream_ibb_send (GabbleBytestreamIface *iface, { GabbleBytestreamIBB *self = GABBLE_BYTESTREAM_IBB (iface); GabbleBytestreamIBBPrivate *priv = GABBLE_BYTESTREAM_IBB_GET_PRIVATE (self); - gboolean result; guint sent; if (priv->state != GABBLE_BYTESTREAM_STATE_OPEN) @@ -579,7 +579,7 @@ gabble_bytestream_ibb_send (GabbleBytestreamIface *iface, return TRUE; } - sent = send_data (self, str, len, &result); + sent = send_data (self, str, len); if (sent < len) { guint remaining; @@ -602,7 +602,7 @@ gabble_bytestream_ibb_send (GabbleBytestreamIface *iface, change_write_blocked_state (self, TRUE); } - return result; + return TRUE; } void |