[libsoup/carlosgc/io-split: 4/5] Turn soup-message-io into an interface
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/carlosgc/io-split: 4/5] Turn soup-message-io into an interface
- Date: Thu, 22 Apr 2021 11:11:21 +0000 (UTC)
commit e5f222d2bdb927b120c5c3890b6e320c0d901876
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Thu Apr 22 11:17:32 2021 +0200
Turn soup-message-io into an interface
docs/reference/meson.build | 2 +
libsoup/meson.build | 1 +
libsoup/soup-client-message-io.c | 99 +++++++++++++
libsoup/soup-client-message-io.h | 71 +++++++++
libsoup/soup-connection.c | 8 +-
libsoup/soup-connection.h | 8 +-
libsoup/soup-message-io-completion.h | 18 +++
libsoup/soup-message-io-data.h | 11 +-
libsoup/soup-message-io.c | 271 ++++++++++++++++++-----------------
libsoup/soup-message-private.h | 29 +---
libsoup/soup-message.c | 111 +++++++++++++-
libsoup/soup-types.h | 1 +
12 files changed, 453 insertions(+), 177 deletions(-)
---
diff --git a/docs/reference/meson.build b/docs/reference/meson.build
index 10e64bb8..38792607 100644
--- a/docs/reference/meson.build
+++ b/docs/reference/meson.build
@@ -38,6 +38,8 @@ ignore_headers = [
'soup-uri-utils-private.h',
'soup-session-feature-private.h',
'soup-message-metrics-private.h',
+ 'soup-client-message-io.h',
+ 'soup-message-io-completion.h',
]
mkdb_args = [
diff --git a/libsoup/meson.build b/libsoup/meson.build
index 7bdaf0ac..ceafe5a1 100644
--- a/libsoup/meson.build
+++ b/libsoup/meson.build
@@ -51,6 +51,7 @@ soup_sources = [
'soup-body-input-stream.c',
'soup-body-output-stream.c',
'soup-client-input-stream.c',
+ 'soup-client-message-io.c',
'soup-connection.c',
'soup-date-utils.c',
'soup-filter-input-stream.c',
diff --git a/libsoup/soup-client-message-io.c b/libsoup/soup-client-message-io.c
new file mode 100644
index 00000000..1db0c2e3
--- /dev/null
+++ b/libsoup/soup-client-message-io.c
@@ -0,0 +1,99 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "soup-client-message-io.h"
+
+void
+soup_client_message_io_destroy (SoupClientMessageIO *io)
+{
+ if (!io)
+ return;
+
+ io->funcs->destroy (io);
+}
+
+void
+soup_client_message_io_finished (SoupClientMessageIO *io)
+{
+ io->funcs->finished (io);
+}
+
+void
+soup_client_message_io_stolen (SoupClientMessageIO *io)
+{
+ io->funcs->stolen (io);
+}
+
+void
+soup_client_message_io_send_item (SoupClientMessageIO *io,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data)
+{
+ io->funcs->send_item (io, item, completion_cb, user_data);
+}
+
+void
+soup_client_message_io_pause (SoupClientMessageIO *io)
+{
+ io->funcs->pause (io);
+}
+
+void
+soup_client_message_io_unpause (SoupClientMessageIO *io)
+{
+ io->funcs->unpause (io);
+}
+
+gboolean
+soup_client_message_io_is_paused (SoupClientMessageIO *io)
+{
+ return io->funcs->is_paused (io);
+}
+
+void
+soup_client_message_io_run (SoupClientMessageIO *io,
+ gboolean blocking)
+{
+ io->funcs->run (io, blocking);
+}
+
+gboolean
+soup_client_message_io_run_until_read (SoupClientMessageIO *io,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return io->funcs->run_until_read (io, cancellable, error);
+}
+
+void
+soup_client_message_io_run_until_read_async (SoupClientMessageIO *io,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ io->funcs->run_until_read_async (io, io_priority, cancellable, callback, user_data);
+}
+
+gboolean
+soup_client_message_io_run_until_finish (SoupClientMessageIO *io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return io->funcs->run_until_finish (io, blocking, cancellable, error);
+}
+
+GInputStream *
+soup_client_message_io_get_response_stream (SoupClientMessageIO *io,
+ GError **error)
+{
+ return io->funcs->get_response_stream (io, error);
+}
diff --git a/libsoup/soup-client-message-io.h b/libsoup/soup-client-message-io.h
new file mode 100644
index 00000000..22f9bc47
--- /dev/null
+++ b/libsoup/soup-client-message-io.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ */
+
+#pragma once
+
+#include "soup-message-io-data.h"
+#include "soup-message-queue-item.h"
+
+typedef struct _SoupClientMessageIO SoupClientMessageIO;
+
+typedef struct {
+ void (*destroy) (SoupClientMessageIO *io);
+ void (*finished) (SoupClientMessageIO *io);
+ void (*stolen) (SoupClientMessageIO *io);
+ void (*send_item) (SoupClientMessageIO *io,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data);
+ GInputStream *(*get_response_stream) (SoupClientMessageIO *io,
+ GError **error);
+ void (*pause) (SoupClientMessageIO *io);
+ void (*unpause) (SoupClientMessageIO *io);
+ gboolean (*is_paused) (SoupClientMessageIO *io);
+ void (*run) (SoupClientMessageIO *io,
+ gboolean blocking);
+ gboolean (*run_until_read) (SoupClientMessageIO *io,
+ GCancellable *cancellable,
+ GError **error);
+ void (*run_until_read_async) (SoupClientMessageIO *io,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*run_until_finish) (SoupClientMessageIO *io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error);
+} SoupClientMessageIOFuncs;
+
+struct _SoupClientMessageIO {
+ const SoupClientMessageIOFuncs *funcs;
+};
+
+void soup_client_message_io_destroy (SoupClientMessageIO *io);
+void soup_client_message_io_finished (SoupClientMessageIO *io);
+void soup_client_message_io_stolen (SoupClientMessageIO *io);
+void soup_client_message_io_send_item (SoupClientMessageIO *io,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data);
+void soup_client_message_io_pause (SoupClientMessageIO *io);
+void soup_client_message_io_unpause (SoupClientMessageIO *io);
+gboolean soup_client_message_io_is_paused (SoupClientMessageIO *io);
+void soup_client_message_io_run (SoupClientMessageIO *io,
+ gboolean blocking);
+gboolean soup_client_message_io_run_until_read (SoupClientMessageIO *io,
+ GCancellable *cancellable,
+ GError **error);
+void soup_client_message_io_run_until_read_async (SoupClientMessageIO *io,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean soup_client_message_io_run_until_finish (SoupClientMessageIO *io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error);
+GInputStream *soup_client_message_io_get_response_stream (SoupClientMessageIO *io,
+ GError **error);
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 3e52da6d..1c36fb89 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -32,7 +32,7 @@ typedef struct {
gboolean ssl;
SoupMessage *current_msg;
- SoupClientMessageIOData *io_data;
+ SoupClientMessageIO *io_data;
SoupConnectionState state;
time_t unused_timeout;
GSource *idle_timeout_src;
@@ -85,7 +85,7 @@ soup_connection_finalize (GObject *object)
g_clear_pointer (&priv->proxy_uri, g_uri_unref);
g_clear_pointer (&priv->socket_props, soup_socket_properties_unref);
- g_clear_pointer (&priv->io_data, soup_client_message_io_data_free);
+ g_clear_pointer (&priv->io_data, soup_client_message_io_destroy);
g_clear_object (&priv->remote_connectable);
g_clear_object (&priv->current_msg);
@@ -1030,7 +1030,7 @@ soup_connection_get_ever_used (SoupConnection *conn)
return priv->unused_timeout == 0;
}
-SoupClientMessageIOData *
+SoupClientMessageIO *
soup_connection_setup_message_io (SoupConnection *conn,
SoupMessage *msg)
{
@@ -1057,7 +1057,7 @@ soup_connection_message_io_finished (SoupConnection *conn,
SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
g_assert (priv->current_msg == msg);
- g_clear_pointer (&priv->io_data, soup_client_message_io_data_free);
+ g_clear_pointer (&priv->io_data, soup_client_message_io_destroy);
}
GTlsCertificate *
diff --git a/libsoup/soup-connection.h b/libsoup/soup-connection.h
index bc0550d9..ca4dcd5a 100644
--- a/libsoup/soup-connection.h
+++ b/libsoup/soup-connection.h
@@ -65,10 +65,10 @@ void soup_connection_set_reusable (SoupConnection *conn,
gboolean soup_connection_get_ever_used (SoupConnection *conn);
-SoupClientMessageIOData *soup_connection_setup_message_io (SoupConnection *conn,
- SoupMessage *msg);
-void soup_connection_message_io_finished (SoupConnection *conn,
- SoupMessage *msg);
+SoupClientMessageIO *soup_connection_setup_message_io (SoupConnection *conn,
+ SoupMessage *msg);
+void soup_connection_message_io_finished (SoupConnection *conn,
+ SoupMessage *msg);
GTlsCertificate *soup_connection_get_tls_certificate (SoupConnection *conn);
GTlsCertificateFlags soup_connection_get_tls_certificate_errors (SoupConnection *conn);
diff --git a/libsoup/soup-message-io-completion.h b/libsoup/soup-message-io-completion.h
new file mode 100644
index 00000000..78b8b88f
--- /dev/null
+++ b/libsoup/soup-message-io-completion.h
@@ -0,0 +1,18 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2000-2003, Ximian, Inc.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+typedef enum {
+ SOUP_MESSAGE_IO_COMPLETE,
+ SOUP_MESSAGE_IO_INTERRUPTED,
+ SOUP_MESSAGE_IO_STOLEN
+} SoupMessageIOCompletion;
+
+typedef void (*SoupMessageIOCompletionFn) (GObject *msg,
+ SoupMessageIOCompletion completion,
+ gpointer user_data);
diff --git a/libsoup/soup-message-io-data.h b/libsoup/soup-message-io-data.h
index f2b7a9ce..80722239 100644
--- a/libsoup/soup-message-io-data.h
+++ b/libsoup/soup-message-io-data.h
@@ -9,6 +9,7 @@
#include "soup-filter-input-stream.h"
#include "soup-message-headers.h"
#include "soup-message-io-source.h"
+#include "soup-message-io-completion.h"
typedef enum {
SOUP_MESSAGE_IO_STATE_NOT_STARTED,
@@ -32,16 +33,6 @@ typedef enum {
(SOUP_MESSAGE_IO_STATE_ACTIVE (state) && \
state != SOUP_MESSAGE_IO_STATE_BODY_DONE)
-typedef enum {
- SOUP_MESSAGE_IO_COMPLETE,
- SOUP_MESSAGE_IO_INTERRUPTED,
- SOUP_MESSAGE_IO_STOLEN
-} SoupMessageIOCompletion;
-
-typedef void (*SoupMessageIOCompletionFn) (GObject *msg,
- SoupMessageIOCompletion completion,
- gpointer user_data);
-
typedef struct {
GIOStream *iostream;
SoupFilterInputStream *istream;
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index 8e318ad6..4ab32ee7 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -27,10 +27,12 @@
#include "soup-message-private.h"
#include "soup-message-metrics-private.h"
#include "soup-message-queue-item.h"
+#include "soup-client-message-io.h"
#include "soup-misc.h"
#include "soup-uri-utils-private.h"
-struct _SoupClientMessageIOData {
+typedef struct {
+ SoupClientMessageIO iface;
SoupMessageIOData base;
SoupMessageQueueItem *item;
@@ -40,16 +42,15 @@ struct _SoupClientMessageIOData {
#ifdef HAVE_SYSPROF
gint64 begin_time_nsec;
#endif
-};
+} SoupClientMessageIOData;
#define RESPONSE_BLOCK_SIZE 8192
#define HEADER_SIZE_LIMIT (64 * 1024)
-void
-soup_client_message_io_data_free (SoupClientMessageIOData *io)
+static void
+soup_client_message_io_data_destroy (SoupClientMessageIO *iface)
{
- if (!io)
- return;
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
soup_message_io_data_cleanup (&io->base);
soup_message_queue_item_unref (io->item);
@@ -66,9 +67,10 @@ soup_client_message_io_data_get_priority (SoupClientMessageIOData *io)
return g_task_get_priority (io->item->task);
}
-void
-soup_client_message_io_finished (SoupClientMessageIOData *io)
+static void
+soup_client_message_io_data_finished (SoupClientMessageIO *iface)
{
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
SoupMessageIOCompletionFn completion_cb;
gpointer completion_data;
SoupMessageIOCompletion completion;
@@ -90,9 +92,10 @@ soup_client_message_io_finished (SoupClientMessageIOData *io)
g_object_unref (msg);
}
-void
-soup_client_message_io_stolen (SoupClientMessageIOData *io)
+static void
+soup_client_message_io_data_stolen (SoupClientMessageIO *iface)
{
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
SoupMessageIOCompletionFn completion_cb;
gpointer completion_data;
SoupMessage *msg;
@@ -162,7 +165,7 @@ request_body_stream_wrote_data_cb (SoupMessage *msg,
guint count,
gboolean is_metadata)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *client_io = (SoupClientMessageIOData *)soup_message_get_io_data (msg);
if (client_io->metrics) {
client_io->metrics->request_body_bytes_sent += count;
@@ -186,7 +189,7 @@ request_body_stream_wrote_cb (GOutputStream *ostream,
nwrote = g_output_stream_splice_finish (ostream, result, &error);
- io = soup_message_get_io_data (msg);
+ io = (SoupClientMessageIOData *)soup_message_get_io_data (msg);
if (!io || !io->base.async_wait || io->base.body_ostream != ostream) {
g_clear_error (&error);
g_object_unref (msg);
@@ -216,7 +219,7 @@ closed_async (GObject *source,
SoupClientMessageIOData *io;
GCancellable *async_wait;
- io = soup_message_get_io_data (msg);
+ io = (SoupClientMessageIOData *)soup_message_get_io_data (msg);
if (!io || !io->base.async_wait || io->base.body_ostream != body_ostream) {
g_object_unref (msg);
return;
@@ -317,11 +320,13 @@ write_headers (SoupMessage *msg,
* socket not writable, write is complete, etc).
*/
static gboolean
-io_write (SoupMessage *msg, gboolean blocking,
- GCancellable *cancellable, GError **error)
+io_write (SoupClientMessageIOData *client_io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
+ SoupMessage *msg = client_io->item->msg;
SoupSessionFeature *logger;
gssize nwrote;
@@ -510,7 +515,7 @@ static void
response_network_stream_read_data_cb (SoupMessage *msg,
guint count)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *client_io = (SoupClientMessageIOData *)soup_message_get_io_data (msg);
if (client_io->base.read_state < SOUP_MESSAGE_IO_STATE_BODY_START)
client_io->metrics->response_header_bytes_received += count;
@@ -525,11 +530,13 @@ response_network_stream_read_data_cb (SoupMessage *msg,
* socket not readable, read is complete, etc).
*/
static gboolean
-io_read (SoupMessage *msg, gboolean blocking,
- GCancellable *cancellable, GError **error)
+io_read (SoupClientMessageIOData *client_io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
+ SoupMessage *msg = client_io->item->msg;
gboolean succeeded;
gboolean is_first_read;
gushort extra_bytes;
@@ -599,7 +606,7 @@ io_read (SoupMessage *msg, gboolean blocking,
/* If this was "101 Switching Protocols", then
* the session may have stolen the connection...
*/
- if (client_io != soup_message_get_io_data (msg))
+ if (client_io != (SoupClientMessageIOData *)soup_message_get_io_data (msg))
return FALSE;
soup_message_cleanup_response (msg);
@@ -701,12 +708,14 @@ io_read (SoupMessage *msg, gboolean blocking,
static gboolean
request_is_restartable (SoupMessage *msg, GError *error)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
- SoupMessageIOData *io = &client_io->base;
+ SoupClientMessageIOData *client_io = (SoupClientMessageIOData *)soup_message_get_io_data (msg);
+ SoupMessageIOData *io;
if (!client_io)
return FALSE;
+ io = &client_io->base;
+
return (io->read_state <= SOUP_MESSAGE_IO_STATE_HEADERS &&
io->read_header_buf->len == 0 &&
soup_connection_get_ever_used (client_io->item->conn) &&
@@ -718,12 +727,15 @@ request_is_restartable (SoupMessage *msg, GError *error)
}
static gboolean
-io_run_until (SoupMessage *msg, gboolean blocking,
- SoupMessageIOState read_state, SoupMessageIOState write_state,
- GCancellable *cancellable, GError **error)
+io_run_until (SoupClientMessageIOData *client_io,
+ gboolean blocking,
+ SoupMessageIOState read_state,
+ SoupMessageIOState write_state,
+ GCancellable *cancellable,
+ GError **error)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
+ SoupMessage *msg = client_io->item->msg;
gboolean progress = TRUE, done;
GError *my_error = NULL;
@@ -738,13 +750,14 @@ io_run_until (SoupMessage *msg, gboolean blocking,
g_object_ref (msg);
- while (progress && soup_message_get_io_data (msg) == client_io && !io->paused && !io->async_wait &&
+ while (progress && (SoupClientMessageIOData *)soup_message_get_io_data (msg) == client_io &&
+ !io->paused && !io->async_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);
+ progress = io_read (client_io, blocking, cancellable, &my_error);
else if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->write_state))
- progress = io_write (msg, blocking, cancellable, &my_error);
+ progress = io_write (client_io, blocking, cancellable, &my_error);
else
progress = FALSE;
}
@@ -753,7 +766,7 @@ io_run_until (SoupMessage *msg, gboolean blocking,
g_propagate_error (error, my_error);
g_object_unref (msg);
return FALSE;
- } else if (soup_message_get_io_data (msg) != client_io) {
+ } else if ((SoupClientMessageIOData *)soup_message_get_io_data (msg) != client_io) {
g_set_error_literal (error, G_IO_ERROR,
G_IO_ERROR_CANCELLED,
_("Operation was cancelled"));
@@ -818,7 +831,7 @@ soup_message_io_finish (SoupMessage *msg,
GError *error)
{
if (request_is_restartable (msg, error)) {
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)soup_message_get_io_data (msg);
/* Connection got closed, but we can safely try again. */
io->item->state = SOUP_MESSAGE_RESTARTING;
@@ -829,19 +842,22 @@ soup_message_io_finish (SoupMessage *msg,
soup_message_io_finished (msg);
}
+static void soup_client_message_io_data_run (SoupClientMessageIO *iface, gboolean blocking);
+
static gboolean
io_run_ready (SoupMessage *msg, gpointer user_data)
{
- soup_message_io_run (msg, FALSE);
+ soup_client_message_io_data_run (soup_message_get_io_data (msg), FALSE);
return FALSE;
}
-void
-soup_message_io_run (SoupMessage *msg,
- gboolean blocking)
+static void
+soup_client_message_io_data_run (SoupClientMessageIO *iface,
+ gboolean blocking)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *client_io = (SoupClientMessageIOData *)iface;
SoupMessageIOData *io = &client_io->base;
+ SoupMessage *msg = client_io->item->msg;
GError *error = NULL;
if (io->io_source) {
@@ -852,7 +868,7 @@ soup_message_io_run (SoupMessage *msg,
g_object_ref (msg);
- if (io_run_until (msg, blocking,
+ if (io_run_until (client_io, blocking,
SOUP_MESSAGE_IO_STATE_DONE,
SOUP_MESSAGE_IO_STATE_DONE,
client_io->item->cancellable, &error)) {
@@ -867,7 +883,7 @@ soup_message_io_run (SoupMessage *msg,
soup_client_message_io_data_get_priority (client_io));
g_source_attach (io->io_source, g_main_context_get_thread_default ());
} else {
- if (soup_message_get_io_data (msg) == client_io)
+ if ((SoupClientMessageIOData *)soup_message_get_io_data (msg) == client_io)
soup_message_io_finish (msg, error);
g_error_free (error);
@@ -876,27 +892,27 @@ soup_message_io_run (SoupMessage *msg,
g_object_unref (msg);
}
-gboolean
-soup_message_io_run_until_read (SoupMessage *msg,
- GCancellable *cancellable,
- GError **error)
+static gboolean
+soup_client_message_io_data_run_until_read (SoupClientMessageIO *iface,
+ GCancellable *cancellable,
+ GError **error)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
+ SoupMessage *msg = io->item->msg;
- if (io_run_until (msg, TRUE,
+ if (io_run_until (io, TRUE,
SOUP_MESSAGE_IO_STATE_BODY,
SOUP_MESSAGE_IO_STATE_ANY,
cancellable, error))
return TRUE;
- if (soup_message_get_io_data (msg) == io)
+ if ((SoupClientMessageIOData *)soup_message_get_io_data (msg) == io)
soup_message_io_finish (msg, *error);
return FALSE;
}
-static void io_run_until_read_async (SoupMessage *msg,
- GTask *task);
+static void io_run_until_read_async (SoupClientMessageIOData *io, GTask *task);
static gboolean
io_run_until_read_ready (SoupMessage *msg,
@@ -904,16 +920,16 @@ io_run_until_read_ready (SoupMessage *msg,
{
GTask *task = user_data;
- io_run_until_read_async (msg, task);
+ io_run_until_read_async ((SoupClientMessageIOData *)soup_message_get_io_data (msg), task);
return FALSE;
}
static void
-io_run_until_read_async (SoupMessage *msg,
- GTask *task)
+io_run_until_read_async (SoupClientMessageIOData *client_io,
+ GTask *task)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
+ SoupMessage *msg = client_io->item->msg;
GError *error = NULL;
if (io->io_source) {
@@ -922,7 +938,7 @@ io_run_until_read_async (SoupMessage *msg,
io->io_source = NULL;
}
- if (io_run_until (msg, FALSE,
+ if (io_run_until (client_io, FALSE,
SOUP_MESSAGE_IO_STATE_BODY,
SOUP_MESSAGE_IO_STATE_ANY,
g_task_get_cancellable (task),
@@ -942,42 +958,37 @@ io_run_until_read_async (SoupMessage *msg,
return;
}
- if (soup_message_get_io_data (msg) == client_io)
+ if ((SoupClientMessageIOData *)soup_message_get_io_data (msg) == client_io)
soup_message_io_finish (msg, error);
g_task_return_error (task, error);
g_object_unref (task);
}
-void
-soup_message_io_run_until_read_async (SoupMessage *msg,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+static void
+soup_client_message_io_data_run_until_read_async (SoupClientMessageIO *iface,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
+ SoupMessage *msg = io->item->msg;
GTask *task;
task = g_task_new (msg, cancellable, callback, user_data);
g_task_set_priority (task, io_priority);
- io_run_until_read_async (msg, task);
+ io_run_until_read_async (io, 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
-soup_message_io_run_until_finish (SoupMessage *msg,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error)
+static gboolean
+soup_client_message_io_data_run_until_finish (SoupClientMessageIO *iface,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
+ SoupMessage *msg = io->item->msg;
gboolean success;
g_object_ref (msg);
@@ -987,7 +998,7 @@ soup_message_io_run_until_finish (SoupMessage *msg,
io->base.read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
}
- success = io_run_until (msg, blocking,
+ success = io_run_until (io, blocking,
SOUP_MESSAGE_IO_STATE_DONE,
SOUP_MESSAGE_IO_STATE_DONE,
cancellable, error);
@@ -997,35 +1008,36 @@ soup_message_io_run_until_finish (SoupMessage *msg,
}
static void
-client_stream_eof (SoupClientInputStream *stream, gpointer user_data)
+client_stream_eof (SoupClientInputStream *stream,
+ SoupClientMessageIOData *io)
{
- SoupMessage *msg = user_data;
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
-
if (io && io->base.read_state == SOUP_MESSAGE_IO_STATE_BODY)
io->base.read_state = SOUP_MESSAGE_IO_STATE_BODY_DONE;
}
-GInputStream *
-soup_message_io_get_response_istream (SoupMessage *msg,
- GError **error)
+static GInputStream *
+soup_client_message_io_data_get_response_stream (SoupClientMessageIO *iface,
+ GError **error)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
+ SoupMessage *msg = io->item->msg;
GInputStream *client_stream;
client_stream = soup_client_input_stream_new (io->base.body_istream, msg);
g_signal_connect (client_stream, "eof",
- G_CALLBACK (client_stream_eof), msg);
+ G_CALLBACK (client_stream_eof), io);
return client_stream;
}
-void
-soup_client_message_io_data_send_item (SoupClientMessageIOData *io,
+static void
+soup_client_message_io_data_send_item (SoupClientMessageIO *iface,
SoupMessageQueueItem *item,
SoupMessageIOCompletionFn completion_cb,
gpointer user_data)
{
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
+
io->item = soup_message_queue_item_ref (item);
io->base.completion_cb = completion_cb;
io->base.completion_data = user_data;
@@ -1042,64 +1054,65 @@ soup_client_message_io_data_send_item (SoupClientMessageIOData *io,
#endif
}
-SoupClientMessageIOData *
-soup_client_message_io_data_new (GIOStream *stream)
-{
- SoupClientMessageIOData *io;
-
- io = g_slice_new0 (SoupClientMessageIOData);
- io->base.iostream = g_object_ref (stream);
- io->base.istream = SOUP_FILTER_INPUT_STREAM (g_io_stream_get_input_stream (io->base.iostream));
- io->base.ostream = g_io_stream_get_output_stream (io->base.iostream);
-
- io->base.read_header_buf = g_byte_array_new ();
- io->base.write_buf = g_string_new (NULL);
-
- io->base.read_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
- io->base.write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
-
- return io;
-}
-
-void
-soup_message_io_pause (SoupMessage *msg)
+static void
+soup_client_message_io_data_pause (SoupClientMessageIO *iface)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
- g_return_if_fail (io != NULL);
g_return_if_fail (io->base.read_state < SOUP_MESSAGE_IO_STATE_BODY);
soup_message_io_data_pause (&io->base);
}
-void
-soup_message_io_unpause (SoupMessage *msg)
+static void
+soup_client_message_io_data_unpause (SoupClientMessageIO *iface)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
- g_return_if_fail (io != NULL);
g_return_if_fail (io->base.read_state < SOUP_MESSAGE_IO_STATE_BODY);
io->base.paused = FALSE;
}
-/**
- * soup_message_io_in_progress:
- * @msg: a #SoupMessage
- *
- * Tests whether or not I/O is currently in progress on @msg.
- *
- * Returns: whether or not I/O is currently in progress.
- **/
-gboolean
-soup_message_io_in_progress (SoupMessage *msg)
+static gboolean
+soup_client_message_io_data_is_paused (SoupClientMessageIO *iface)
{
- return soup_message_get_io_data (msg) != NULL;
+ SoupClientMessageIOData *io = (SoupClientMessageIOData *)iface;
+
+ return io->base.paused;
}
-gboolean
-soup_message_is_io_paused (SoupMessage *msg)
+static const SoupClientMessageIOFuncs io_funcs = {
+ soup_client_message_io_data_destroy,
+ soup_client_message_io_data_finished,
+ soup_client_message_io_data_stolen,
+ soup_client_message_io_data_send_item,
+ soup_client_message_io_data_get_response_stream,
+ soup_client_message_io_data_pause,
+ soup_client_message_io_data_unpause,
+ soup_client_message_io_data_is_paused,
+ soup_client_message_io_data_run,
+ soup_client_message_io_data_run_until_read,
+ soup_client_message_io_data_run_until_read_async,
+ soup_client_message_io_data_run_until_finish
+};
+
+SoupClientMessageIO *
+soup_client_message_io_data_new (GIOStream *stream)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io;
+
+ io = g_slice_new0 (SoupClientMessageIOData);
+ io->base.iostream = g_object_ref (stream);
+ io->base.istream = SOUP_FILTER_INPUT_STREAM (g_io_stream_get_input_stream (io->base.iostream));
+ io->base.ostream = g_io_stream_get_output_stream (io->base.iostream);
+
+ io->base.read_header_buf = g_byte_array_new ();
+ io->base.write_buf = g_string_new (NULL);
+
+ io->base.read_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
+ io->base.write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
+
+ io->iface.funcs = &io_funcs;
- return io && io->base.paused;
+ return (SoupClientMessageIO *)io;
}
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index 10dd232a..d8cfa0bb 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -8,15 +8,12 @@
#include "soup-filter-input-stream.h"
#include "soup-message.h"
-#include "soup-message-io-data.h"
+#include "soup-client-message-io.h"
#include "auth/soup-auth.h"
#include "soup-content-processor.h"
#include "content-sniffer/soup-content-sniffer.h"
#include "soup-session.h"
-typedef struct _SoupClientMessageIOData SoupClientMessageIOData;
-void soup_client_message_io_data_free (SoupClientMessageIOData *io);
-
void soup_message_set_status (SoupMessage *msg,
guint status_code,
const char *reason_phrase);
@@ -48,29 +45,15 @@ SoupAuth *soup_message_get_proxy_auth (SoupMessage *msg);
GUri *soup_message_get_uri_for_auth (SoupMessage *msg);
/* I/O */
-SoupClientMessageIOData *soup_client_message_io_data_new (GIOStream *stream);
-void soup_client_message_io_data_send_item (SoupClientMessageIOData *io,
- SoupMessageQueueItem *item,
- SoupMessageIOCompletionFn completion_cb,
- gpointer user_data);
-void soup_client_message_io_finished (SoupClientMessageIOData *io);
-void soup_client_message_io_stolen (SoupClientMessageIOData *io);
+SoupClientMessageIO *soup_client_message_io_data_new (GIOStream *stream);
void soup_message_io_run (SoupMessage *msg,
gboolean blocking);
void soup_message_io_finished (SoupMessage *msg);
-void soup_message_io_cleanup (SoupMessage *msg);
void soup_message_io_pause (SoupMessage *msg);
void soup_message_io_unpause (SoupMessage *msg);
gboolean soup_message_is_io_paused (SoupMessage *msg);
gboolean soup_message_io_in_progress (SoupMessage *msg);
-gboolean soup_message_io_read_headers (SoupMessage *msg,
- SoupFilterInputStream *stream,
- GByteArray *buffer,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error);
-
gboolean soup_message_io_run_until_finish (SoupMessage *msg,
gboolean blocking,
GCancellable *cancellable,
@@ -88,12 +71,6 @@ gboolean soup_message_io_run_until_read_finish (SoupMessage *msg,
GAsyncResult *result,
GError **error);
-typedef gboolean (*SoupMessageSourceFunc) (SoupMessage *, gpointer);
-GSource *soup_message_io_get_source (SoupMessage *msg,
- GCancellable *cancellable,
- SoupMessageSourceFunc callback,
- gpointer user_data);
-
GInputStream *soup_message_io_get_response_istream (SoupMessage *msg,
GError **error);
@@ -129,7 +106,7 @@ SoupConnection *soup_message_get_connection (SoupMessage *msg);
void soup_message_set_connection (SoupMessage *msg,
SoupConnection *conn);
-SoupClientMessageIOData *soup_message_get_io_data (SoupMessage *msg);
+SoupClientMessageIO *soup_message_get_io_data (SoupMessage *msg);
SoupContentSniffer *soup_message_get_content_sniffer (SoupMessage *msg);
void soup_message_set_content_sniffer (SoupMessage *msg,
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index c39ad4b8..d761ce86 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -59,7 +59,7 @@ struct _SoupMessage {
};
typedef struct {
- SoupClientMessageIOData *io_data;
+ SoupClientMessageIO *io_data;
SoupMessageHeaders *request_headers;
SoupMessageHeaders *response_headers;
@@ -2135,7 +2135,7 @@ soup_message_get_priority (SoupMessage *msg)
return priv->priority;
}
-SoupClientMessageIOData *
+SoupClientMessageIO *
soup_message_get_io_data (SoupMessage *msg)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
@@ -2155,6 +2155,100 @@ soup_message_io_finished (SoupMessage *msg)
soup_client_message_io_finished (g_steal_pointer (&priv->io_data));
}
+void
+soup_message_io_pause (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ g_return_if_fail (priv->io_data != NULL);
+
+ soup_client_message_io_pause (priv->io_data);
+}
+
+void
+soup_message_io_unpause (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ g_return_if_fail (priv->io_data != NULL);
+
+ soup_client_message_io_unpause (priv->io_data);
+}
+
+gboolean
+soup_message_is_io_paused (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ return priv->io_data && soup_client_message_io_is_paused (priv->io_data);
+}
+
+/**
+ * soup_message_io_in_progress:
+ * @msg: a #SoupMessage
+ *
+ * Tests whether or not I/O is currently in progress on @msg.
+ *
+ * Returns: whether or not I/O is currently in progress.
+ **/
+gboolean
+soup_message_io_in_progress (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ return priv->io_data != NULL;
+}
+
+void
+soup_message_io_run (SoupMessage *msg,
+ gboolean blocking)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ soup_client_message_io_run (priv->io_data, blocking);
+}
+
+gboolean
+soup_message_io_run_until_read (SoupMessage *msg,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ return soup_client_message_io_run_until_read (priv->io_data, cancellable, error);
+}
+
+void
+soup_message_io_run_until_read_async (SoupMessage *msg,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ soup_client_message_io_run_until_read_async (priv->io_data, io_priority, cancellable, callback,
user_data);
+}
+
+gboolean
+soup_message_io_run_until_read_finish (SoupMessage *msg,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+gboolean
+soup_message_io_run_until_finish (SoupMessage *msg,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ return soup_client_message_io_run_until_finish (priv->io_data, blocking, cancellable, error);
+}
+
void
soup_message_send_item (SoupMessage *msg,
SoupMessageQueueItem *item,
@@ -2164,8 +2258,17 @@ soup_message_send_item (SoupMessage *msg,
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
priv->io_data = soup_connection_setup_message_io (priv->connection, msg);
- soup_client_message_io_data_send_item (priv->io_data, item,
- completion_cb, user_data);
+ soup_client_message_io_send_item (priv->io_data, item,
+ completion_cb, user_data);
+}
+
+GInputStream *
+soup_message_io_get_response_istream (SoupMessage *msg,
+ GError **error)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ return soup_client_message_io_get_response_stream (priv->io_data, error);
}
SoupContentSniffer *
diff --git a/libsoup/soup-types.h b/libsoup/soup-types.h
index 8ce0505f..dec4ffaa 100644
--- a/libsoup/soup-types.h
+++ b/libsoup/soup-types.h
@@ -35,6 +35,7 @@ typedef struct _SoupWebsocketExtension SoupWebsocketExtension;
typedef struct _SoupConnection SoupConnection;
typedef struct _SoupMessageQueue SoupMessageQueue;
typedef struct _SoupMessageQueueItem SoupMessageQueueItem;
+typedef struct _SoupClientMessageIO SoupClientMessageIO;
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]