static gboolean io_unpause_internal (gpointer msg) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; g_return_val_if_fail (io != NULL, FALSE); io->unpause_source = NULL; if (io->write_tag || io->read_tag) return FALSE; if (io->write_state != SOUP_MESSAGE_IO_STATE_DONE) { io->write_tag = g_signal_connect (io->sock, "writable", G_CALLBACK (io_write), msg); } if (io->read_state != SOUP_MESSAGE_IO_STATE_DONE) { io->read_tag = g_signal_connect (io->sock, "readable", G_CALLBACK (io_read), msg); } if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->write_state)) io_write (io->sock, msg); else if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state)) io_read (io->sock, msg); return FALSE; }
static gboolean io_run_until (SoupMessage *msg, gboolean blocking, SoupMessageIOState read_state, SoupMessageIOState write_state, GCancellable *cancellable, GError **error) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; gboolean progress = TRUE, done; GError *my_error = NULL; if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; else if (!io) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation was cancelled")); return FALSE; } g_object_ref (msg); while (progress && priv->io_data == io && !io->paused && !io->async_close_wait && (io->read_state < read_state || io->write_state < write_state)) { if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state)) progress = io_read (msg, blocking, cancellable, &my_error); else if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->write_state)) progress = io_write (msg, blocking, cancellable, &my_error); else progress = FALSE; } if (my_error) { if (request_is_restartable (msg, my_error)) { /* Connection got closed, but we can safely try again */ g_error_free (my_error); g_set_error_literal (error, SOUP_HTTP_ERROR, SOUP_STATUS_TRY_AGAIN, ""); g_object_unref (msg); return FALSE; } g_propagate_error (error, my_error); g_object_unref (msg); return FALSE; } else if (priv->io_data != io) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation was cancelled")); g_object_unref (msg); return FALSE; } else if (!io->async_close_wait && g_cancellable_set_error_if_cancelled (cancellable, error)) { g_object_unref (msg); return FALSE; } done = (io->read_state >= read_state && io->write_state >= write_state); if (!blocking && !done) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, _("Operation would block")); g_object_unref (msg); return FALSE; } g_object_unref (msg); return done; }