summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2009-11-22 08:41:09 -0500
committerDan Winship <danw@gnome.org>2009-11-22 08:41:09 -0500
commit6ff7ecdd6f52fb4a44cdad9cf9d5deab24645863 (patch)
treec9b551ad8fd8480ee983ced8de0c027834227e67
parentf8ce30a570bdea4da87c69a080101846a0c21588 (diff)
downloadlibsoup-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.c83
-rw-r--r--libsoup/soup-connection.h12
-rw-r--r--libsoup/soup-misc.h9
-rw-r--r--libsoup/soup-session-async.c1
-rw-r--r--libsoup/soup-session-sync.c1
-rw-r--r--libsoup/soup-session.c25
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++;