diff options
author | Dan Winship <danw@gnome.org> | 2009-11-22 08:41:09 -0500 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2009-11-22 08:41:09 -0500 |
commit | 6ff7ecdd6f52fb4a44cdad9cf9d5deab24645863 (patch) | |
tree | c9b551ad8fd8480ee983ced8de0c027834227e67 | |
parent | f8ce30a570bdea4da87c69a080101846a0c21588 (diff) | |
download | libsoup-6ff7ecdd6f52fb4a44cdad9cf9d5deab24645863.tar.gz |
Changes to SoupConnection and SoupSession for debugging
Specifically, to help epiphany's soup-fly extension track connection
usage.
Patch from José Millán Soto,
https://bugzilla.gnome.org/show_bug.cgi?id=598163
-rw-r--r-- | libsoup/soup-connection.c | 83 | ||||
-rw-r--r-- | libsoup/soup-connection.h | 12 | ||||
-rw-r--r-- | libsoup/soup-misc.h | 9 | ||||
-rw-r--r-- | libsoup/soup-session-async.c | 1 | ||||
-rw-r--r-- | libsoup/soup-session-sync.c | 1 | ||||
-rw-r--r-- | libsoup/soup-session.c | 25 |
6 files changed, 107 insertions, 24 deletions
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c index 9f59816f..8cb110c4 100644 --- a/libsoup/soup-connection.c +++ b/libsoup/soup-connection.c @@ -26,6 +26,7 @@ #include "soup-socket.h" #include "soup-ssl.h" #include "soup-uri.h" +#include "soup-enum-types.h" typedef struct { SoupSocket *socket; @@ -63,6 +64,8 @@ enum { PROP_ASYNC_CONTEXT, PROP_TIMEOUT, PROP_IDLE_TIMEOUT, + PROP_STATE, + PROP_MESSAGE, LAST_PROP }; @@ -191,6 +194,20 @@ soup_connection_class_init (SoupConnectionClass *connection_class) "Connection lifetime when idle", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property ( + object_class, PROP_STATE, + g_param_spec_enum (SOUP_CONNECTION_STATE, + "Connection state", + "Current state of connection", + SOUP_TYPE_CONNECTION_STATE, SOUP_CONNECTION_NEW, + G_PARAM_READWRITE)); + g_object_class_install_property ( + object_class, PROP_MESSAGE, + g_param_spec_object (SOUP_CONNECTION_MESSAGE, + "Message", + "Message being processed", + SOUP_TYPE_MESSAGE, + G_PARAM_READABLE)); } @@ -240,6 +257,9 @@ set_property (GObject *object, guint prop_id, case PROP_IDLE_TIMEOUT: priv->idle_timeout = g_value_get_uint (value); break; + case PROP_STATE: + soup_connection_set_state (SOUP_CONNECTION (object), g_value_get_uint (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -274,6 +294,12 @@ get_property (GObject *object, guint prop_id, case PROP_IDLE_TIMEOUT: g_value_set_uint (value, priv->idle_timeout); break; + case PROP_STATE: + g_value_set_enum (value, priv->state); + break; + case PROP_MESSAGE: + g_value_set_object (value, priv->cur_req); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -310,19 +336,28 @@ stop_idle_timer (SoupConnectionPrivate *priv) } static void -set_current_request (SoupConnectionPrivate *priv, SoupMessage *req) +set_current_request (SoupConnection *conn, SoupMessage *req) { + SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn); + g_return_if_fail (priv->cur_req == NULL); + g_object_freeze_notify (G_OBJECT (conn)); + stop_idle_timer (priv); priv->unused_timeout = 0; soup_message_set_io_status (req, SOUP_MESSAGE_IO_STATUS_RUNNING); priv->cur_req = req; + g_object_notify (G_OBJECT (conn), "message"); + if (priv->state == SOUP_CONNECTION_IDLE || req->method != SOUP_METHOD_CONNECT) - priv->state = SOUP_CONNECTION_IN_USE; + soup_connection_set_state (conn, SOUP_CONNECTION_IN_USE); + g_object_add_weak_pointer (G_OBJECT (req), (gpointer)&priv->cur_req); + + g_object_thaw_notify (G_OBJECT (conn)); } static void @@ -330,8 +365,15 @@ clear_current_request (SoupConnection *conn) { SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn); - if (priv->state == SOUP_CONNECTION_IN_USE) + g_object_freeze_notify (G_OBJECT (conn)); + + 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; @@ -339,12 +381,15 @@ clear_current_request (SoupConnection *conn) g_object_remove_weak_pointer (G_OBJECT (priv->cur_req), (gpointer)&priv->cur_req); priv->cur_req = NULL; + g_object_notify (G_OBJECT (conn), "message"); 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)); } static void @@ -378,7 +423,7 @@ socket_connect_result (SoupSocket *sock, guint status, gpointer user_data) g_signal_connect (priv->socket, "disconnected", G_CALLBACK (socket_disconnected), data->conn); - priv->state = SOUP_CONNECTION_IDLE; + soup_connection_set_state (data->conn, SOUP_CONNECTION_IDLE); priv->unused_timeout = time (NULL) + SOUP_CONNECTION_UNUSED_TIMEOUT; start_idle_timer (data->conn); @@ -411,7 +456,7 @@ soup_connection_connect_async (SoupConnection *conn, priv = SOUP_CONNECTION_GET_PRIVATE (conn); g_return_if_fail (priv->socket == NULL); - priv->state = SOUP_CONNECTION_CONNECTING; + soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING); data = g_slice_new (SoupConnectionAsyncConnectData); data->conn = conn; @@ -446,7 +491,7 @@ soup_connection_connect_sync (SoupConnection *conn) priv = SOUP_CONNECTION_GET_PRIVATE (conn); g_return_val_if_fail (priv->socket == NULL, SOUP_STATUS_MALFORMED); - priv->state = SOUP_CONNECTION_CONNECTING; + soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING); priv->socket = soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, priv->remote_addr, @@ -471,7 +516,7 @@ soup_connection_connect_sync (SoupConnection *conn) } if (SOUP_STATUS_IS_SUCCESSFUL (status)) { - priv->state = SOUP_CONNECTION_IDLE; + soup_connection_set_state (conn, SOUP_CONNECTION_IDLE); priv->unused_timeout = time (NULL) + SOUP_CONNECTION_UNUSED_TIMEOUT; start_idle_timer (conn); } else { @@ -541,7 +586,7 @@ soup_connection_disconnect (SoupConnection *conn) if (priv->state < SOUP_CONNECTION_IDLE) return; - priv->state = SOUP_CONNECTION_DISCONNECTED; + soup_connection_set_state (conn, SOUP_CONNECTION_DISCONNECTED); /* NB: this might cause conn to be destroyed. */ g_signal_emit (conn, signals[DISCONNECTED], 0); } @@ -579,12 +624,12 @@ soup_connection_get_state (SoupConnection *conn) pfd.events = G_IO_IN; pfd.revents = 0; if (g_poll (&pfd, 1, 0) == 1) - priv->state = SOUP_CONNECTION_REMOTE_DISCONNECTED; + soup_connection_set_state (conn, SOUP_CONNECTION_REMOTE_DISCONNECTED); } #endif if (priv->state == SOUP_CONNECTION_IDLE && priv->unused_timeout && priv->unused_timeout < time (NULL)) - priv->state = SOUP_CONNECTION_REMOTE_DISCONNECTED; + soup_connection_set_state (conn, SOUP_CONNECTION_REMOTE_DISCONNECTED); return priv->state; } @@ -592,13 +637,21 @@ soup_connection_get_state (SoupConnection *conn) void soup_connection_set_state (SoupConnection *conn, SoupConnectionState state) { + SoupConnectionPrivate *priv; + SoupConnectionState old_state; + g_return_if_fail (SOUP_IS_CONNECTION (conn)); - g_return_if_fail (state > SOUP_CONNECTION_NEW && - state < SOUP_CONNECTION_DISCONNECTED); + g_return_if_fail (state >= SOUP_CONNECTION_NEW && + state <= SOUP_CONNECTION_DISCONNECTED); - SOUP_CONNECTION_GET_PRIVATE (conn)->state = state; - if (state == SOUP_CONNECTION_IDLE) + priv = SOUP_CONNECTION_GET_PRIVATE (conn); + old_state = priv->state; + priv->state = state; + if (state == SOUP_CONNECTION_IDLE && + old_state == SOUP_CONNECTION_IN_USE) clear_current_request (conn); + + g_object_notify (G_OBJECT (conn), "state"); } /** @@ -620,7 +673,7 @@ soup_connection_send_request (SoupConnection *conn, SoupMessage *req) g_return_if_fail (priv->state != SOUP_CONNECTION_NEW && priv->state != SOUP_CONNECTION_DISCONNECTED); if (req != priv->cur_req) - set_current_request (priv, req); + set_current_request (conn, req); soup_message_send_request (req, priv->socket, conn, priv->proxy_uri != NULL); } diff --git a/libsoup/soup-connection.h b/libsoup/soup-connection.h index aa261d25..ae8973e9 100644 --- a/libsoup/soup-connection.h +++ b/libsoup/soup-connection.h @@ -9,6 +9,7 @@ #include <time.h> #include "soup-types.h" +#include "soup-misc.h" G_BEGIN_DECLS @@ -39,15 +40,6 @@ typedef void (*SoupConnectionCallback) (SoupConnection *conn, guint status, gpointer data); -typedef enum { - SOUP_CONNECTION_NEW, - SOUP_CONNECTION_CONNECTING, - SOUP_CONNECTION_IDLE, - SOUP_CONNECTION_IN_USE, - SOUP_CONNECTION_REMOTE_DISCONNECTED, - SOUP_CONNECTION_DISCONNECTED -} SoupConnectionState; - #define SOUP_CONNECTION_REMOTE_ADDRESS "remote-address" #define SOUP_CONNECTION_TUNNEL_ADDRESS "tunnel-address" #define SOUP_CONNECTION_PROXY_URI "proxy-uri" @@ -55,6 +47,8 @@ typedef enum { #define SOUP_CONNECTION_ASYNC_CONTEXT "async-context" #define SOUP_CONNECTION_TIMEOUT "timeout" #define SOUP_CONNECTION_IDLE_TIMEOUT "idle-timeout" +#define SOUP_CONNECTION_STATE "state" +#define SOUP_CONNECTION_MESSAGE "message" SoupConnection *soup_connection_new (const char *propname1, ...) G_GNUC_NULL_TERMINATED; diff --git a/libsoup/soup-misc.h b/libsoup/soup-misc.h index e40fa912..8802340b 100644 --- a/libsoup/soup-misc.h +++ b/libsoup/soup-misc.h @@ -49,6 +49,15 @@ typedef enum { SOUP_SSL_ERROR_CERTIFICATE } SoupSSLError; +typedef enum { + SOUP_CONNECTION_NEW, + SOUP_CONNECTION_CONNECTING, + SOUP_CONNECTION_IDLE, + SOUP_CONNECTION_IN_USE, + SOUP_CONNECTION_REMOTE_DISCONNECTED, + SOUP_CONNECTION_DISCONNECTED +} SoupConnectionState; + G_END_DECLS #endif /* SOUP_MISC_H */ diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c index 731138c6..89af6969 100644 --- a/libsoup/soup-session-async.c +++ b/libsoup/soup-session-async.c @@ -264,6 +264,7 @@ got_connection (SoupConnection *conn, guint status, gpointer session) data->session = session; data->conn = conn; data->item = soup_session_make_connect_message (session, tunnel_addr); + g_signal_emit_by_name (session, "tunneling", conn); g_signal_connect (data->item->msg, "finished", G_CALLBACK (tunnel_connected), data); g_signal_connect (data->item->msg, "restarted", diff --git a/libsoup/soup-session-sync.c b/libsoup/soup-session-sync.c index eba77e46..e1ba325e 100644 --- a/libsoup/soup-session-sync.c +++ b/libsoup/soup-session-sync.c @@ -142,6 +142,7 @@ tunnel_connect (SoupSession *session, SoupConnection *conn, SoupMessageQueueItem *item; guint status; + g_signal_emit_by_name (session, "tunneling", conn); item = soup_session_make_connect_message (session, tunnel_addr); do soup_session_send_queue_item (session, item, conn); diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 9c3efdb4..c4d3044d 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -123,6 +123,8 @@ enum { REQUEST_STARTED, REQUEST_UNQUEUED, AUTHENTICATE, + CONNECTION_CREATED, + TUNNELING, LAST_SIGNAL }; @@ -380,6 +382,27 @@ soup_session_class_init (SoupSessionClass *session_class) SOUP_TYPE_AUTH, G_TYPE_BOOLEAN); + signals[CONNECTION_CREATED] = + g_signal_new ("connection-created", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + soup_marshal_NONE__OBJECT, + G_TYPE_NONE, 1, + SOUP_TYPE_CONNECTION); + + signals[TUNNELING] = + g_signal_new ("tunneling", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + soup_marshal_NONE__OBJECT, + G_TYPE_NONE, 1, + SOUP_TYPE_CONNECTION); + + /* properties */ /** * SOUP_SESSION_PROXY_URI: @@ -1217,6 +1240,8 @@ soup_session_get_connection (SoupSession *session, G_CALLBACK (connection_disconnected), session); + g_signal_emit (session, signals[CONNECTION_CREATED], 0, conn); + g_hash_table_insert (priv->conns, conn, host); priv->num_conns++; |