diff options
author | Dan Winship <danw@novell.com> | 2005-08-16 14:34:29 +0000 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2005-08-16 14:34:29 +0000 |
commit | 5fb4fbfc9b55a5e8b79127d938f390c4d460a86f (patch) | |
tree | badd31056a81f05d40cc57adf731675835777c17 | |
parent | fafb234f9843bc6f2a31fbe35ecf13b36310d61a (diff) | |
download | libsoup-5fb4fbfc9b55a5e8b79127d938f390c4d460a86f.tar.gz |
Fix a connection leak reported by Tambet.
2005-08-16 Dan Winship <danw@novell.com>
Fix a connection leak reported by Tambet.
* libsoup/soup-connection.c (send_request): rather than tracking
the message progress via signals, call
soup_message_send_request_internal() and have it call
soup_connection_release() when it's done.
(request_restarted, request_done): gone
(clear_current_request): handle disconnecting (if necessary) and
updating last_used time here.
(soup_connection_release): Call clear_current_request().
(dispose): Call clear_current_request()
* libsoup/soup-message-client-io.c
(soup_message_send_request_internal): New. Takes a SoupConnection
in addition to the other args, and passes that on to
soup-message-io.
* libsoup/soup-message-io.c (SoupMessageIOData): add a
SoupConnection field.
(io_cleanup): if io->conn is set, unref it.
(soup_message_io_stop): if io->conn is set, and we ended in a
clean state, call soup_connection_release() on it.
(soup_message_io_client): Add a SoupConnection arg, which gets
reffed and stored in io->conn.
* TODO: misc updates
-rw-r--r-- | ChangeLog | 29 | ||||
-rw-r--r-- | libsoup/soup-connection.c | 48 | ||||
-rw-r--r-- | libsoup/soup-message-client-io.c | 9 | ||||
-rw-r--r-- | libsoup/soup-message-io.c | 11 | ||||
-rw-r--r-- | libsoup/soup-message-private.h | 6 |
5 files changed, 65 insertions, 38 deletions
@@ -1,3 +1,32 @@ +2005-08-16 Dan Winship <danw@novell.com> + + Fix a connection leak reported by Tambet. + + * libsoup/soup-connection.c (send_request): rather than tracking + the message progress via signals, call + soup_message_send_request_internal() and have it call + soup_connection_release() when it's done. + (request_restarted, request_done): gone + (clear_current_request): handle disconnecting (if necessary) and + updating last_used time here. + (soup_connection_release): Call clear_current_request(). + (dispose): Call clear_current_request() + + * libsoup/soup-message-client-io.c + (soup_message_send_request_internal): New. Takes a SoupConnection + in addition to the other args, and passes that on to + soup-message-io. + + * libsoup/soup-message-io.c (SoupMessageIOData): add a + SoupConnection field. + (io_cleanup): if io->conn is set, unref it. + (soup_message_io_stop): if io->conn is set, and we ended in a + clean state, call soup_connection_release() on it. + (soup_message_io_client): Add a SoupConnection arg, which gets + reffed and stored in io->conn. + + * TODO: misc updates + 2005-06-20 Dan Winship <danw@novell.com> * configure.in: Bump version to 2.2.4 diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c index 17676f99..88ede8aa 100644 --- a/libsoup/soup-connection.c +++ b/libsoup/soup-connection.c @@ -25,6 +25,7 @@ #include "soup-connection.h" #include "soup-marshal.h" #include "soup-message.h" +#include "soup-message-private.h" #include "soup-message-filter.h" #include "soup-misc.h" #include "soup-socket.h" @@ -79,8 +80,8 @@ static void set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void request_done (SoupMessage *req, gpointer user_data); static void send_request (SoupConnection *conn, SoupMessage *req); +static void clear_current_request (SoupConnection *conn); static void init (GObject *object) @@ -113,8 +114,7 @@ dispose (GObject *object) { SoupConnection *conn = SOUP_CONNECTION (object); - if (conn->priv->cur_req) - request_done (conn->priv->cur_req, conn); + clear_current_request (conn); soup_connection_disconnect (conn); G_OBJECT_CLASS (parent_class)->dispose (object); @@ -319,6 +319,11 @@ static void clear_current_request (SoupConnection *conn) { if (conn->priv->cur_req) { + if (!soup_message_is_keepalive (conn->priv->cur_req)) + soup_connection_disconnect (conn); + else + conn->priv->last_used = time (NULL); + g_object_remove_weak_pointer (G_OBJECT (conn->priv->cur_req), (gpointer *)conn->priv->cur_req); conn->priv->cur_req = NULL; @@ -651,47 +656,16 @@ soup_connection_last_used (SoupConnection *conn) } static void -request_restarted (SoupMessage *req, gpointer conn) -{ - if (!soup_message_is_keepalive (req)) - soup_connection_disconnect (conn); -} - -static void -request_done (SoupMessage *req, gpointer user_data) -{ - SoupConnection *conn = user_data; - - clear_current_request (conn); - conn->priv->last_used = time (NULL); - - if (!soup_message_is_keepalive (req)) - soup_connection_disconnect (conn); - - g_signal_handlers_disconnect_by_func (req, request_done, conn); - g_signal_handlers_disconnect_by_func (req, request_restarted, conn); - g_object_unref (conn); -} - -static void send_request (SoupConnection *conn, SoupMessage *req) { - g_object_ref (conn); - if (req != conn->priv->cur_req) { set_current_request (conn, req); - - g_signal_connect (req, "restarted", - G_CALLBACK (request_restarted), conn); - g_signal_connect (req, "finished", - G_CALLBACK (request_done), conn); - if (conn->priv->filter) soup_message_filter_setup_message (conn->priv->filter, req); } - soup_message_send_request (req, conn->priv->socket, - conn->priv->proxy_uri != NULL); + soup_message_send_request_internal (req, conn->priv->socket, conn, + conn->priv->proxy_uri != NULL); } /** @@ -742,7 +716,7 @@ soup_connection_release (SoupConnection *conn) { g_return_if_fail (SOUP_IS_CONNECTION (conn)); - conn->priv->in_use = FALSE; + clear_current_request (conn); } /** diff --git a/libsoup/soup-message-client-io.c b/libsoup/soup-message-client-io.c index fdc64294..596b30d8 100644 --- a/libsoup/soup-message-client-io.c +++ b/libsoup/soup-message-client-io.c @@ -172,8 +172,15 @@ void soup_message_send_request (SoupMessage *req, SoupSocket *sock, gboolean is_via_proxy) { + soup_message_send_request_internal (req, sock, NULL, is_via_proxy); +} + +void +soup_message_send_request_internal (SoupMessage *req, SoupSocket *sock, + SoupConnection *conn, gboolean is_via_proxy) +{ soup_message_cleanup_response (req); - soup_message_io_client (req, sock, + soup_message_io_client (req, sock, conn, get_request_headers, parse_response_headers, GUINT_TO_POINTER (is_via_proxy)); diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c index 7350378b..f28833d0 100644 --- a/libsoup/soup-message-io.c +++ b/libsoup/soup-message-io.c @@ -12,6 +12,7 @@ #include <stdlib.h> #include <string.h> +#include "soup-connection.h" #include "soup-message.h" #include "soup-message-private.h" #include "soup-socket.h" @@ -36,6 +37,7 @@ typedef enum { typedef struct { SoupSocket *sock; + SoupConnection *conn; SoupMessageIOMode mode; SoupMessageIOState read_state; @@ -81,6 +83,8 @@ io_cleanup (SoupMessage *msg) if (io->sock) g_object_unref (io->sock); + if (io->conn) + g_object_unref (io->conn); if (io->read_buf) g_byte_array_free (io->read_buf, TRUE); @@ -122,6 +126,8 @@ soup_message_io_stop (SoupMessage *msg) if (io->read_state != SOUP_MESSAGE_IO_STATE_DONE) soup_socket_disconnect (io->sock); + else if (io->conn) + soup_connection_release (io->conn); } #define SOUP_MESSAGE_IO_EOL "\r\n" @@ -698,6 +704,7 @@ new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode, * soup_message_io_client: * @msg: a #SoupMessage * @sock: socket to send @msg across + * @conn: the connection that owns @sock (or %NULL) * @get_headers_cb: callback function to generate request headers * @parse_headers_cb: callback function to parse response headers * @user_data: data to pass to the callbacks @@ -708,6 +715,7 @@ new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode, **/ void soup_message_io_client (SoupMessage *msg, SoupSocket *sock, + SoupConnection *conn, SoupMessageGetHeadersFn get_headers_cb, SoupMessageParseHeadersFn parse_headers_cb, gpointer user_data) @@ -717,6 +725,9 @@ soup_message_io_client (SoupMessage *msg, SoupSocket *sock, 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->read_body = &msg->response; io->write_body = &msg->request; diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h index c17bc78d..a705ad1a 100644 --- a/libsoup/soup-message-private.h +++ b/libsoup/soup-message-private.h @@ -39,8 +39,14 @@ typedef guint (*SoupMessageParseHeadersFn)(SoupMessage *msg, guint *content_len, gpointer user_data); +void soup_message_send_request_internal (SoupMessage *req, + SoupSocket *sock, + SoupConnection *conn, + gboolean via_proxy); + void soup_message_io_client (SoupMessage *msg, SoupSocket *sock, + SoupConnection *conn, SoupMessageGetHeadersFn get_headers_cb, SoupMessageParseHeadersFn parse_headers_cb, gpointer user_data); |