diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-03-11 09:54:19 +0000 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-03-11 10:17:57 +0000 |
commit | b7e4c63cd9490018d7f8db138de98168ae4e4050 (patch) | |
tree | 194bd33296f0ae9d32669bbdb04ab4c22fd67283 | |
parent | 0dd3a10f6dbfa6f580eed5ae0f492eaaac2e540f (diff) |
porter: don't close twice if we close in a send callbackmessage-example
We need to decide before we complete the "send stanza" asynchronous
operation whether we have a close result pending. If we don't, we can
get into a pickle if the callback to send_async calls close_async. The
problem is that close_async doesn't use the same stanza queue as
send_async so needs special-casing.
For example: Previously, we send a stanza using send_async. The simple
async result would be completed with g_simple_async_result_complete()
and the callback to send_async would be called. However, if in the
callback close_async is called, the stream close is sent directly with
wocky_xmpp_connection_send_close_async and priv->close_result is
assigned. Once the callback returns, send_stanza_cb continues BUT at
the end there is a test for whether there is a close result
pending. This is for when you send a whole bunch of stanzas followed
by a close request, so the porter waits until all the stanzas are sent
before sending the stream close, which is cool. However,
priv->close_result is now != NULL so the porter thinks we're in
exactly that case -- that we're waiting until all the stanzas are sent
and will try and send a stream close afterwards. As we've already done
that the xmpp connection will say "hey another send operation pending"
and everything will fall apart.
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
-rw-r--r-- | wocky/wocky-porter.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/wocky/wocky-porter.c b/wocky/wocky-porter.c index d83c035..b167b96 100644 --- a/wocky/wocky-porter.c +++ b/wocky/wocky-porter.c @@ -90,6 +90,7 @@ struct _WockyPorterPrivate GCancellable *receive_cancellable; GSimpleAsyncResult *close_result; + gboolean waiting_to_close; gboolean remote_closed; gboolean local_closed; GCancellable *close_cancellable; @@ -750,12 +751,13 @@ send_stanza_cb (GObject *source, } } - if (priv->close_result != NULL && + if (priv->waiting_to_close && g_queue_get_length (priv->sending_queue) == 0) { /* Queue is empty and we are waiting to close the connection. */ DEBUG ("Queue has been flushed. Closing the connection."); send_close (self); + priv->waiting_to_close = FALSE; } g_object_unref (self); @@ -1429,6 +1431,7 @@ wocky_porter_close_async (WockyPorter *self, { DEBUG ("Sending queue is not empty. Flushing it before " "closing the connection."); + priv->waiting_to_close = TRUE; return; } |