diff options
author | Dan Winship <danw@gnome.org> | 2012-09-17 13:53:48 -0400 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2012-09-17 13:55:36 -0400 |
commit | 0c825d4a0b89c103ea798fe7fb816e3a0c48534e (patch) | |
tree | a74948cee531ac63e9f83de04b3ca39138f21d90 | |
parent | eee8574f876404dd24fb238224a72981bfc2f4f5 (diff) | |
download | libsoup-0c825d4a0b89c103ea798fe7fb816e3a0c48534e.tar.gz |
SoupSessionAsync: destroy the I/O GSource when returning a result
When a soup_request_send_async() gets cancelled, we were leaving its
GSource active, causing it to be triggered later, sometimes causing
criticals. Fix that.
https://bugzilla.gnome.org/show_bug.cgi?id=683404
-rw-r--r-- | libsoup/soup-message-queue.c | 4 | ||||
-rw-r--r-- | libsoup/soup-message-queue.h | 1 | ||||
-rw-r--r-- | libsoup/soup-session-async.c | 14 |
3 files changed, 14 insertions, 5 deletions
diff --git a/libsoup/soup-message-queue.c b/libsoup/soup-message-queue.c index e4640358..2a60446e 100644 --- a/libsoup/soup-message-queue.c +++ b/libsoup/soup-message-queue.c @@ -187,6 +187,10 @@ soup_message_queue_item_unref (SoupMessageQueueItem *item) soup_uri_free (item->proxy_uri); if (item->result) g_object_unref (item->result); + if (item->io_source) { + g_source_destroy (item->io_source); + g_source_unref (item->io_source); + } soup_message_queue_item_set_connection (item, NULL); g_slice_free (SoupMessageQueueItem, item); } diff --git a/libsoup/soup-message-queue.h b/libsoup/soup-message-queue.h index cd153813..0f948cc3 100644 --- a/libsoup/soup-message-queue.h +++ b/libsoup/soup-message-queue.h @@ -41,6 +41,7 @@ struct _SoupMessageQueueItem { SoupURI *proxy_uri; SoupConnection *conn; GSimpleAsyncResult *result; + GSource *io_source; guint paused : 1; guint new_api : 1; diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c index ffc306ae..398cc0fe 100644 --- a/libsoup/soup-session-async.c +++ b/libsoup/soup-session-async.c @@ -478,6 +478,11 @@ send_request_return_result (SoupMessageQueueItem *item, simple = item->result; item->result = NULL; + if (item->io_source) { + g_source_destroy (item->io_source); + g_clear_pointer (&item->io_source, g_source_unref); + } + if (error) g_simple_async_result_take_error (simple, error); else if (SOUP_STATUS_IS_TRANSPORT_ERROR (item->msg->status_code)) { @@ -614,6 +619,7 @@ read_ready_cb (SoupMessage *msg, gpointer user_data) { SoupMessageQueueItem *item = user_data; + g_clear_pointer (&item->io_source, g_source_unref); try_run_until_read (item); return FALSE; } @@ -623,7 +629,6 @@ try_run_until_read (SoupMessageQueueItem *item) { GError *error = NULL; GInputStream *stream = NULL; - GSource *source; if (soup_message_io_run_until_read (item->msg, item->cancellable, &error)) stream = soup_message_io_get_response_istream (item->msg, &error); @@ -653,10 +658,9 @@ try_run_until_read (SoupMessageQueueItem *item) } g_clear_error (&error); - source = soup_message_io_get_source (item->msg, item->cancellable, - read_ready_cb, item); - g_source_attach (source, soup_session_get_async_context (item->session)); - g_source_unref (source); + item->io_source = soup_message_io_get_source (item->msg, item->cancellable, + read_ready_cb, item); + g_source_attach (item->io_source, soup_session_get_async_context (item->session)); } static void |