[libsoup/wip/http2-b: 1/3] soup-message-io: document/rename broken GSource



commit 4179ebdeee36f2c9d57aab322399994fafde849e
Author: Dan Winship <danw gnome org>
Date:   Tue Dec 9 12:01:45 2014 +0100

    soup-message-io: document/rename broken GSource
    
    The source returned by soup_message_io_get_source() depends on the
    current state of the message, and so is not reusable. Document this,
    and rename it to soup_message_io_get_oneshot_source().
    
    Fix SoupClientInputStream, which was previously reusing its source.
    Also, remove the "FIXME" code there, since the SoupSession bug it
    referred to did eventually get fixed.

 libsoup/soup-client-input-stream.c |   50 +++++++++++-------------------------
 libsoup/soup-message-io.c          |   16 +++++++----
 libsoup/soup-message-private.h     |   10 +++---
 libsoup/soup-session.c             |    7 ++---
 4 files changed, 33 insertions(+), 50 deletions(-)
---
diff --git a/libsoup/soup-client-input-stream.c b/libsoup/soup-client-input-stream.c
index 0264cb7..72a166c 100644
--- a/libsoup/soup-client-input-stream.c
+++ b/libsoup/soup-client-input-stream.c
@@ -136,18 +136,8 @@ soup_client_input_stream_close_fn (GInputStream  *stream,
        return success;
 }
 
-static gboolean
-idle_finish_close (gpointer user_data)
-{
-       GTask *task = user_data;
-
-       g_task_return_boolean (task, TRUE);
-       g_object_unref (task);
-       return FALSE;
-}
-
-static gboolean
-close_async_ready (SoupMessage *msg, gpointer user_data)
+static void
+try_close_async (SoupMessage *msg, gpointer user_data)
 {
        GTask *task = user_data;
        SoupClientInputStream *cistream = g_task_get_source_object (task);
@@ -157,25 +147,23 @@ close_async_ready (SoupMessage *msg, gpointer user_data)
                                               g_task_get_cancellable (task),
                                               &error) &&
            g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
+               GSource *source;
+
                g_error_free (error);
-               return TRUE;
+               source = soup_message_io_get_oneshot_source (msg,
+                                                            g_task_get_cancellable (task),
+                                                            NULL, NULL);
+               g_task_attach_source (task, source, (GSourceFunc) try_close_async);
+               g_source_unref (source);
        }
 
-       soup_message_io_finished (cistream->priv->msg);
+       soup_message_io_finished (msg);
 
-       if (error) {
+       if (error)
                g_task_return_error (task, error);
-               g_object_unref (task);
-               return FALSE;
-       }
-
-       /* Due to a historical accident, SoupSessionAsync relies on us
-        * waiting one extra cycle after run_until_finish() returns.
-        * Ugh. FIXME later when it's easier to do.
-        */
-       soup_add_idle (g_main_context_get_thread_default (),
-                      idle_finish_close, task);
-       return FALSE;
+       else
+               g_task_return_boolean (task, TRUE);
+       g_object_unref (task);
 }
 
 static void
@@ -187,18 +175,10 @@ soup_client_input_stream_close_async (GInputStream        *stream,
 {
        SoupClientInputStream *cistream = SOUP_CLIENT_INPUT_STREAM (stream);
        GTask *task;
-       GSource *source;
 
        task = g_task_new (stream, cancellable, callback, user_data);
        g_task_set_priority (task, priority);
-
-       if (close_async_ready (cistream->priv->msg, task) == G_SOURCE_CONTINUE) {
-               source = soup_message_io_get_source (cistream->priv->msg,
-                                                    cancellable, NULL, NULL);
-
-               g_task_attach_source (task, source, (GSourceFunc) close_async_ready);
-               g_source_unref (source);
-       }
+       try_close_async (cistream->priv->msg, task);
 }
 
 static gboolean
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index db98dc2..abe909f 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -781,7 +781,8 @@ message_source_dispatch (GSource     *source,
        SoupMessageSourceFunc func = (SoupMessageSourceFunc)callback;
        SoupMessageSource *message_source = (SoupMessageSource *)source;
 
-       return (*func) (message_source->msg, user_data);
+       (*func) (message_source->msg, user_data);
+       return G_SOURCE_REMOVE;
 }
 
 static void
@@ -825,9 +826,13 @@ static GSourceFuncs message_source_funcs =
        (GSourceDummyMarshal)g_cclosure_marshal_generic,
 };
 
+/* The source returned by this function is only usable in the current
+ * state; after it fires, you need a new one if you want to wait
+ * again.
+ */
 GSource *
-soup_message_io_get_source (SoupMessage *msg, GCancellable *cancellable,
-                           SoupMessageSourceFunc callback, gpointer user_data)
+soup_message_io_get_oneshot_source (SoupMessage *msg, GCancellable *cancellable,
+                                   SoupMessageSourceFunc callback, gpointer user_data)
 {
        SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
        SoupMessageIOData *io = priv->io_data;
@@ -966,11 +971,10 @@ io_run_until (SoupMessage *msg, gboolean blocking,
        return done;
 }
 
-static gboolean
+static void
 io_run_ready (SoupMessage *msg, gpointer user_data)
 {
        io_run (msg, FALSE);
-       return FALSE;
 }
 
 static void
@@ -997,7 +1001,7 @@ io_run (SoupMessage *msg, gboolean blocking)
                soup_message_io_finished (msg);
        } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
                g_clear_error (&error);
-               io->io_source = soup_message_io_get_source (msg, NULL, io_run_ready, msg);
+               io->io_source = soup_message_io_get_oneshot_source (msg, NULL, io_run_ready, msg);
                g_source_attach (io->io_source, io->async_context);
        } else if (error && priv->io_data == io) {
                if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_TRY_AGAIN))
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index 9860dee..9cb4b19 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -119,11 +119,11 @@ gboolean soup_message_io_run_until_finish (SoupMessage   *msg,
                                           GCancellable  *cancellable,
                                           GError       **error);
 
-typedef gboolean (*SoupMessageSourceFunc) (SoupMessage *, gpointer);
-GSource *soup_message_io_get_source       (SoupMessage           *msg,
-                                          GCancellable          *cancellable,
-                                          SoupMessageSourceFunc  callback,
-                                          gpointer               user_data);
+typedef void (*SoupMessageSourceFunc) (SoupMessage *, gpointer);
+GSource *soup_message_io_get_oneshot_source (SoupMessage           *msg,
+                                            GCancellable          *cancellable,
+                                            SoupMessageSourceFunc  callback,
+                                            gpointer               user_data);
 
 GInputStream *soup_message_io_get_response_istream (SoupMessage  *msg,
                                                    GError      **error);
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index f2bd34b..4eee825 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -3976,14 +3976,13 @@ send_async_maybe_complete (SoupMessageQueueItem *item,
 
 static void try_run_until_read (SoupMessageQueueItem *item);
 
-static gboolean
+static void
 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;
 }
 
 static void
@@ -4018,8 +4017,8 @@ try_run_until_read (SoupMessageQueueItem *item)
        }
 
        g_clear_error (&error);
-       item->io_source = soup_message_io_get_source (item->msg, item->cancellable,
-                                                     read_ready_cb, item);
+       item->io_source = soup_message_io_get_oneshot_source (item->msg, item->cancellable,
+                                                             read_ready_cb, item);
        g_source_attach (item->io_source, soup_session_get_async_context (item->session));
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]