Misc SoupConnection API improvements
authorDan Winship <danw@gnome.org>
Sat, 29 May 2010 13:05:55 +0000 (15:05 +0200)
committerDan Winship <danw@gnome.org>
Wed, 9 Jun 2010 15:23:00 +0000 (11:23 -0400)
Use GCancellables in connect_async/connect_sync (plus updates needed
for behavior changes caused by that). Make
soup_connection_disconnect() always emit the signal if the connection
state wasn't already DISCONNECTED, even if it wasn't yet connected
before. Remove some dead code in clear_current_request. Remove some
more-or-less redundant arguments in soup_message_send_request().

libsoup/soup-connection.c
libsoup/soup-connection.h
libsoup/soup-message-client-io.c
libsoup/soup-message-io.c
libsoup/soup-message-private.h
libsoup/soup-session-async.c
libsoup/soup-session-sync.c
libsoup/soup-socket.c

index 98e2730..58614ac 100644 (file)
@@ -386,14 +386,6 @@ clear_current_request (SoupConnection *conn)
        g_object_freeze_notify (G_OBJECT (conn));
 
        priv->unused_timeout = 0;
-
-       if (priv->state == SOUP_CONNECTION_IN_USE) {
-               /* We don't use soup_connection_set_state here since
-                * it may call clear_current_request()...
-                */
-               priv->state = SOUP_CONNECTION_IDLE;
-               g_object_notify (G_OBJECT (conn), "state");
-       }
        start_idle_timer (conn);
        if (priv->cur_req) {
                SoupMessage *cur_req = priv->cur_req;
@@ -403,8 +395,6 @@ clear_current_request (SoupConnection *conn)
 
                if (!soup_message_is_keepalive (cur_req))
                        soup_connection_disconnect (conn);
-               else
-                       soup_message_io_stop (cur_req);
        }
 
        g_object_thaw_notify (G_OBJECT (conn));
@@ -457,16 +447,9 @@ socket_connect_result (SoupSocket *sock, guint status, gpointer user_data)
        g_slice_free (SoupConnectionAsyncConnectData, data);
 }
 
-/**
- * soup_connection_connect_async:
- * @conn: the connection
- * @callback: callback to call when the connection succeeds or fails
- * @user_data: data for @callback
- *
- * Asynchronously connects @conn.
- **/
 void
 soup_connection_connect_async (SoupConnection *conn,
+                              GCancellable *cancellable,
                               SoupConnectionCallback callback,
                               gpointer user_data)
 {
@@ -492,20 +475,12 @@ soup_connection_connect_async (SoupConnection *conn,
                                 SOUP_SOCKET_TIMEOUT, priv->io_timeout,
                                 "clean-dispose", TRUE,
                                 NULL);
-       soup_socket_connect_async (priv->socket, NULL,
+       soup_socket_connect_async (priv->socket, cancellable,
                                   socket_connect_result, data);
 }
 
-/**
- * soup_connection_connect_sync:
- * @conn: the connection
- *
- * Synchronously connects @conn.
- *
- * Return value: the soup status
- **/
 guint
-soup_connection_connect_sync (SoupConnection *conn)
+soup_connection_connect_sync (SoupConnection *conn, GCancellable *cancellable)
 {
        SoupConnectionPrivate *priv;
        guint status;
@@ -525,7 +500,7 @@ soup_connection_connect_sync (SoupConnection *conn)
                                 "clean-dispose", TRUE,
                                 NULL);
 
-       status = soup_socket_connect_sync (priv->socket, NULL);
+       status = soup_socket_connect_sync (priv->socket, cancellable);
 
        if (!SOUP_STATUS_IS_SUCCESSFUL (status))
                goto fail;
@@ -534,7 +509,7 @@ soup_connection_connect_sync (SoupConnection *conn)
                          G_CALLBACK (socket_disconnected), conn);
 
        if (priv->ssl_creds && !priv->tunnel_addr) {
-               if (!soup_socket_start_ssl (priv->socket, NULL)) {
+               if (!soup_socket_start_ssl (priv->socket, cancellable)) {
                        status = SOUP_STATUS_SSL_FAILED;
                        goto fail;
                }
@@ -594,22 +569,25 @@ void
 soup_connection_disconnect (SoupConnection *conn)
 {
        SoupConnectionPrivate *priv;
+       SoupConnectionState old_state;
 
        g_return_if_fail (SOUP_IS_CONNECTION (conn));
        priv = SOUP_CONNECTION_GET_PRIVATE (conn);
 
-       soup_connection_set_state (conn, SOUP_CONNECTION_DISCONNECTED);
-       if (!priv->socket)
-               return;
+       old_state = priv->state;
+       if (old_state != SOUP_CONNECTION_DISCONNECTED)
+               soup_connection_set_state (conn, SOUP_CONNECTION_DISCONNECTED);
 
-       g_signal_handlers_disconnect_by_func (priv->socket,
-                                             socket_disconnected, conn);
-       soup_socket_disconnect (priv->socket);
-       g_object_unref (priv->socket);
-       priv->socket = NULL;
+       if (priv->socket) {
+               g_signal_handlers_disconnect_by_func (priv->socket,
+                                                     socket_disconnected, conn);
+               soup_socket_disconnect (priv->socket);
+               g_object_unref (priv->socket);
+               priv->socket = NULL;
+       }
 
-       /* NB: this might cause conn to be destroyed. */
-       g_signal_emit (conn, signals[DISCONNECTED], 0);
+       if (old_state != SOUP_CONNECTION_DISCONNECTED)
+               g_signal_emit (conn, signals[DISCONNECTED], 0);
 }
 
 SoupSocket *
@@ -628,6 +606,14 @@ soup_connection_get_proxy_uri (SoupConnection *conn)
        return SOUP_CONNECTION_GET_PRIVATE (conn)->proxy_uri;
 }
 
+gboolean
+soup_connection_is_via_proxy (SoupConnection *conn)
+{
+       g_return_val_if_fail (SOUP_IS_CONNECTION (conn), FALSE);
+
+       return SOUP_CONNECTION_GET_PRIVATE (conn)->proxy_uri != NULL;
+}
+
 SoupConnectionState
 soup_connection_get_state (SoupConnection *conn)
 {
@@ -704,6 +690,5 @@ soup_connection_send_request (SoupConnection *conn, SoupMessage *req)
 
        if (req != priv->cur_req)
                set_current_request (conn, req);
-       soup_message_send_request (req, priv->socket, conn,
-                                  priv->proxy_uri != NULL);
+       soup_message_send_request (req, conn);
 }
index 17b9f7b..558a465 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef SOUP_CONNECTION_H
 #define SOUP_CONNECTION_H 1
 
-#include <time.h>
+#include <gio/gio.h>
 
 #include "soup-types.h"
 #include "soup-misc.h"
@@ -55,9 +55,11 @@ SoupConnection *soup_connection_new            (const char       *propname1,
                                                ...) G_GNUC_NULL_TERMINATED;
 
 void            soup_connection_connect_async  (SoupConnection   *conn,
+                                               GCancellable     *cancellable,
                                                SoupConnectionCallback callback,
                                                gpointer          user_data);
-guint           soup_connection_connect_sync   (SoupConnection   *conn);
+guint           soup_connection_connect_sync   (SoupConnection   *conn,
+                                               GCancellable     *cancellable);
 SoupAddress    *soup_connection_get_tunnel_addr(SoupConnection   *conn);
 gboolean        soup_connection_start_ssl      (SoupConnection   *conn);
 
@@ -65,6 +67,7 @@ void            soup_connection_disconnect     (SoupConnection   *conn);
 
 SoupSocket     *soup_connection_get_socket     (SoupConnection   *conn);
 SoupURI        *soup_connection_get_proxy_uri  (SoupConnection   *conn);
+gboolean        soup_connection_is_via_proxy   (SoupConnection   *conn);
 
 SoupConnectionState soup_connection_get_state  (SoupConnection   *conn);
 void                soup_connection_set_state  (SoupConnection   *conn,
index 618652f..0c091e6 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "soup-message-private.h"
 #include "soup-auth.h"
+#include "soup-connection.h"
 #include "soup-headers.h"
 #include "soup-uri.h"
 
@@ -76,7 +77,7 @@ get_request_headers (SoupMessage *req, GString *header,
                     SoupEncoding *encoding, gpointer user_data)
 {
        SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
-       gboolean proxy = GPOINTER_TO_UINT (user_data);
+       SoupConnection *conn = user_data;
        SoupURI *uri = soup_message_get_uri (req);
        char *uri_host;
        char *uri_string;
@@ -92,6 +93,8 @@ get_request_headers (SoupMessage *req, GString *header,
                /* CONNECT URI is hostname:port for tunnel destination */
                uri_string = g_strdup_printf ("%s:%d", uri_host, uri->port);
        } else {
+               gboolean proxy = soup_connection_is_via_proxy (conn);
+
                /* Proxy expects full URI to destination. Otherwise
                 * just the path.
                 */
@@ -143,12 +146,12 @@ get_request_headers (SoupMessage *req, GString *header,
 }
 
 void
-soup_message_send_request (SoupMessage *req, SoupSocket *sock,
-                          SoupConnection *conn, gboolean is_via_proxy)
+soup_message_send_request (SoupMessage    *msg,
+                          SoupConnection *conn)
 {
-       soup_message_cleanup_response (req);
-       soup_message_io_client (req, sock, conn,
+       soup_message_cleanup_response (msg);
+       soup_message_io_client (msg, conn,
                                get_request_headers,
                                parse_response_headers,
-                               GUINT_TO_POINTER (is_via_proxy));
+                               conn);
 }
index 02f2e45..324b147 100644 (file)
@@ -1043,19 +1043,18 @@ new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
 }
 
 void
-soup_message_io_client (SoupMessage *msg, SoupSocket *sock,
-                       SoupConnection *conn,
+soup_message_io_client (SoupMessage *msg, SoupConnection *conn,
                        SoupMessageGetHeadersFn get_headers_cb,
                        SoupMessageParseHeadersFn parse_headers_cb,
                        gpointer user_data)
 {
        SoupMessageIOData *io;
+       SoupSocket *sock = soup_connection_get_socket (conn);
 
        io = new_iostate (msg, sock, SOUP_MESSAGE_IO_CLIENT,
                          get_headers_cb, parse_headers_cb, user_data);
 
-       if (conn)
-               io->conn = g_object_ref (conn);
+       io->conn = g_object_ref (conn);
 
        io->read_body       = msg->response_body;
        io->write_body      = msg->request_body;
index f279303..cd8a94e 100644 (file)
@@ -62,14 +62,11 @@ typedef guint    (*SoupMessageParseHeadersFn)(SoupMessage      *msg,
                                              gpointer          user_data);
 
 void           soup_message_send_request        (SoupMessage       *req,
-                                                SoupSocket        *sock,
-                                                SoupConnection    *conn,
-                                                gboolean           via_proxy);
+                                                SoupConnection    *conn);
 void           soup_message_read_request        (SoupMessage       *req,
                                                 SoupSocket        *sock);
 
 void soup_message_io_client  (SoupMessage               *msg,
-                             SoupSocket                *sock,
                              SoupConnection            *conn,
                              SoupMessageGetHeadersFn    get_headers_cb,
                              SoupMessageParseHeadersFn  parse_headers_cb,
index c0630ca..6df4ca4 100644 (file)
@@ -336,7 +336,8 @@ run_queue (SoupSessionAsync *sa)
                        continue;
 
                if (soup_connection_get_state (conn) == SOUP_CONNECTION_NEW) {
-                       soup_connection_connect_async (conn, got_connection,
+                       soup_connection_connect_async (conn, item->cancellable,
+                                                      got_connection,
                                                       g_object_ref (session));
                } else
                        soup_session_send_queue_item (session, item, conn);
index 100ce38..dd3cc82 100644 (file)
@@ -211,7 +211,7 @@ wait_for_connection (SoupMessageQueueItem *item)
        conn = soup_session_get_connection (session, item, &try_pruning);
        if (conn) {
                if (soup_connection_get_state (conn) == SOUP_CONNECTION_NEW) {
-                       status = soup_connection_connect_sync (conn);
+                       status = soup_connection_connect_sync (conn, item->cancellable);
 
                        if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
                                soup_session_connection_failed (session, conn, status);
index 871ec69..7ebe5bc 100644 (file)
@@ -133,8 +133,10 @@ soup_socket_init (SoupSocket *sock)
 static void
 disconnect_internal (SoupSocketPrivate *priv)
 {
-       g_io_channel_unref (priv->iochannel);
-       priv->iochannel = NULL;
+       if (priv->iochannel) {
+               g_io_channel_unref (priv->iochannel);
+               priv->iochannel = NULL;
+       }
        priv->sockfd = -1;
 
        if (priv->read_src) {
@@ -672,6 +674,12 @@ idle_connect_result (gpointer user_data)
        } else
                status = SOUP_STATUS_OK;
 
+       /* Have to do this before calling the callback... */
+       if (sacd->cancel_id) {
+               g_signal_handler_disconnect (sacd->cancellable, sacd->cancel_id);
+               sacd->cancel_id = 0;
+       }
+
        sacd->callback (sacd->sock, status, sacd->user_data);
        free_sacd (sacd);
        return FALSE;