diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2020-09-30 10:12:18 +0200 |
---|---|---|
committer | Carlos Garcia Campos <carlos.gcampos@gmail.com> | 2020-10-01 05:51:40 +0000 |
commit | 7deb882083f703f4b7821b1d7bc8261459d8d9e8 (patch) | |
tree | a8bc6a55e57edd35154f2ed24605db5e173bbbec /libsoup/soup-message-io.c | |
parent | e8aea38cb261f8bd7d348a4c76e8b05bde859eb0 (diff) | |
download | libsoup-7deb882083f703f4b7821b1d7bc8261459d8d9e8.tar.gz |
session: use gio async style for soup_message_io_run_until_read
Make soup_message_io_run_until_read the sync one and add
soup_message_io_run_until_read_async and
soup_message_io_run_until_read_finish. The async version handles would
block error and all other error handling has been moved to
soup-message-io too, since it's shared with io_run.
Diffstat (limited to 'libsoup/soup-message-io.c')
-rw-r--r-- | libsoup/soup-message-io.c | 129 |
1 files changed, 110 insertions, 19 deletions
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c index f9da4a9b..26f6a58a 100644 --- a/libsoup/soup-message-io.c +++ b/libsoup/soup-message-io.c @@ -1035,6 +1035,26 @@ io_run_until (SoupMessage *msg, gboolean blocking, return done; } +static void +soup_message_io_update_status (SoupMessage *msg, + GError *error) +{ + if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_TRY_AGAIN)) { + SoupMessageIOData *io = soup_message_get_io_data (msg); + + io->item->state = SOUP_MESSAGE_RESTARTING; + } else if (error->domain == G_TLS_ERROR) { + soup_message_set_status_full (msg, + SOUP_STATUS_SSL_FAILED, + error->message); + } else if (!SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code) && + !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + soup_message_set_status (msg, SOUP_STATUS_IO_ERROR); + } + + soup_message_io_finished (msg); +} + static gboolean io_run_ready (SoupMessage *msg, gpointer user_data) { @@ -1067,21 +1087,13 @@ io_run (SoupMessage *msg, gboolean blocking) g_clear_error (&error); io->io_source = soup_message_io_get_source (msg, NULL, io_run_ready, msg); g_source_attach (io->io_source, io->async_context); - } else if (error && soup_message_get_io_data (msg) == io) { - if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_TRY_AGAIN)) - io->item->state = SOUP_MESSAGE_RESTARTING; - else if (error->domain == G_TLS_ERROR) { - soup_message_set_status_full (msg, - SOUP_STATUS_SSL_FAILED, - error->message); - } else if (!SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) - soup_message_set_status (msg, SOUP_STATUS_IO_ERROR); - - g_error_free (error); - soup_message_io_finished (msg); - } else if (error) + } else { + if (soup_message_get_io_data (msg) == io) + soup_message_io_update_status (msg, error); g_error_free (error); + } + g_object_unref (msg); g_clear_object (&cancellable); } @@ -1097,13 +1109,92 @@ soup_message_io_run_until_write (SoupMessage *msg, gboolean blocking, } gboolean -soup_message_io_run_until_read (SoupMessage *msg, gboolean blocking, - GCancellable *cancellable, GError **error) +soup_message_io_run_until_read (SoupMessage *msg, + GCancellable *cancellable, + GError **error) { - return io_run_until (msg, blocking, - SOUP_MESSAGE_IO_STATE_BODY, - SOUP_MESSAGE_IO_STATE_ANY, - cancellable, error); + SoupMessageIOData *io = soup_message_get_io_data (msg); + + if (io_run_until (msg, TRUE, + SOUP_MESSAGE_IO_STATE_BODY, + SOUP_MESSAGE_IO_STATE_ANY, + cancellable, error)) + return TRUE; + + if (soup_message_get_io_data (msg) == io) + soup_message_io_update_status (msg, *error); + + return FALSE; +} + +static void io_run_until_read_async (SoupMessage *msg, + GTask *task); + +static gboolean +io_run_until_read_ready (SoupMessage *msg, + gpointer user_data) +{ + GTask *task = user_data; + + io_run_until_read_async (msg, task); + return FALSE; +} + +static void +io_run_until_read_async (SoupMessage *msg, + GTask *task) +{ + SoupMessageIOData *io = soup_message_get_io_data (msg); + GError *error = NULL; + + if (io->io_source) { + g_source_destroy (io->io_source); + g_source_unref (io->io_source); + io->io_source = NULL; + } + + if (io_run_until (msg, FALSE, + SOUP_MESSAGE_IO_STATE_BODY, + SOUP_MESSAGE_IO_STATE_ANY, + g_task_get_cancellable (task), + &error)) { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { + g_error_free (error); + io->io_source = soup_message_io_get_source (msg, NULL, io_run_until_read_ready, task); + g_source_attach (io->io_source, io->async_context); + return; + } + + if (soup_message_get_io_data (msg) == io) + soup_message_io_update_status (msg, error); + + g_task_return_error (task, error); + g_object_unref (task); +} + +void +soup_message_io_run_until_read_async (SoupMessage *msg, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (msg, cancellable, callback, user_data); + io_run_until_read_async (msg, task); +} + +gboolean +soup_message_io_run_until_read_finish (SoupMessage *msg, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); } gboolean |