[libsoup] soup-server: leak fixes
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] soup-server: leak fixes
- Date: Tue, 3 Mar 2015 03:01:25 +0000 (UTC)
commit 36d472e866abfdeedb31effc14dbf896b8060731
Author: Dan Winship <danw gnome org>
Date: Mon Mar 2 18:28:42 2015 -0500
soup-server: leak fixes
Fix some leaks and generally do a better job of cleaning up
connections/sockets when shutting down a SoupServer.
libsoup/soup-server.c | 94 +++++++++++++++++++++++--------------------------
1 files changed, 44 insertions(+), 50 deletions(-)
---
diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c
index 84d5bc0..fec9ceb 100644
--- a/libsoup/soup-server.c
+++ b/libsoup/soup-server.c
@@ -250,7 +250,7 @@ soup_server_dispose (GObject *object)
priv->disposed = TRUE;
soup_server_disconnect (server);
- G_OBJECT_CLASS (soup_server_parent_class)->finalize (object);
+ G_OBJECT_CLASS (soup_server_parent_class)->dispose (object);
}
static void
@@ -267,30 +267,6 @@ soup_server_finalize (GObject *object)
g_free (priv->server_header);
- while (priv->clients) {
- SoupClientContext *client = priv->clients->data;
- SoupSocket *sock = g_object_ref (client->sock);
-
- priv->clients = g_slist_remove (priv->clients, client);
-
- /* keep a ref on the client context so it doesn't get destroyed
- * when we finish the message; the SoupSocket::disconnect
- * handler will refer to client->server later when the socket is
- * disconnected.
- */
- soup_client_context_ref (client);
-
- if (client->msg) {
- soup_message_set_status (client->msg, SOUP_STATUS_IO_ERROR);
- soup_message_io_finished (client->msg);
- }
-
- soup_socket_disconnect (sock);
- g_object_unref (sock);
-
- soup_client_context_unref (client);
- }
-
soup_path_map_free (priv->handlers);
g_slist_free_full (priv->auth_domains, g_object_unref);
@@ -1140,6 +1116,7 @@ soup_server_get_listeners (SoupServer *server)
}
static void start_request (SoupServer *, SoupClientContext *);
+static void socket_disconnected (SoupSocket *sock, SoupClientContext *client);
static SoupClientContext *
soup_client_context_new (SoupServer *server, SoupSocket *sock)
@@ -1147,7 +1124,9 @@ soup_client_context_new (SoupServer *server, SoupSocket *sock)
SoupClientContext *client = g_slice_new0 (SoupClientContext);
client->server = server;
- client->sock = sock;
+ client->sock = g_object_ref (sock);
+ g_signal_connect (sock, "disconnected",
+ G_CALLBACK (socket_disconnected), client);
client->ref_count = 1;
return client;
@@ -1174,10 +1153,14 @@ soup_client_context_ref (SoupClientContext *client)
static void
soup_client_context_unref (SoupClientContext *client)
{
- if (--client->ref_count == 0) {
- soup_client_context_cleanup (client);
- g_slice_free (SoupClientContext, client);
- }
+ if (--client->ref_count != 0)
+ return;
+
+ soup_client_context_cleanup (client);
+
+ g_signal_handlers_disconnect_by_func (client->sock, socket_disconnected, client);
+ g_object_unref (client->sock);
+ g_slice_free (SoupClientContext, client);
}
static void
@@ -1185,36 +1168,37 @@ request_finished (SoupMessage *msg, SoupMessageIOCompletion completion, gpointer
{
SoupClientContext *client = user_data;
SoupServer *server = client->server;
+ SoupServerPrivate *priv = SOUP_SERVER_GET_PRIVATE (server);
SoupSocket *sock = client->sock;
gboolean failed;
if (completion == SOUP_MESSAGE_IO_STOLEN) {
soup_client_context_unref (client);
g_object_unref (msg);
- g_object_unref (sock);
return;
}
- soup_message_finished (msg);
+ /* Complete the message, assuming it actually really started. */
+ if (msg->method) {
+ soup_message_finished (msg);
- failed = (completion == SOUP_MESSAGE_IO_INTERRUPTED ||
- msg->status_code == SOUP_STATUS_IO_ERROR);
- g_signal_emit (server,
- failed ? signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED],
- 0, msg, client);
+ failed = (completion == SOUP_MESSAGE_IO_INTERRUPTED ||
+ msg->status_code == SOUP_STATUS_IO_ERROR);
+ g_signal_emit (server,
+ failed ? signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED],
+ 0, msg, client);
+ }
if (completion == SOUP_MESSAGE_IO_COMPLETE &&
soup_socket_is_connected (sock) &&
- soup_message_is_keepalive (msg)) {
- /* Start a new request */
- soup_client_context_cleanup (client);
+ soup_message_is_keepalive (msg) &&
+ priv->listeners) {
start_request (server, client);
} else {
- soup_socket_disconnect (sock);
+ soup_socket_disconnect (client->sock);
soup_client_context_unref (client);
}
g_object_unref (msg);
- g_object_unref (sock);
}
/* "" was never documented as meaning the same thing as "/", but it
@@ -1439,8 +1423,6 @@ start_request (SoupServer *server, SoupClientContext *client)
g_signal_emit (server, signals[REQUEST_STARTED], 0,
msg, client);
- g_object_ref (client->sock);
-
soup_message_read_request (msg, client->sock,
priv->legacy_iface == NULL,
request_finished, client);
@@ -1452,8 +1434,11 @@ socket_disconnected (SoupSocket *sock, SoupClientContext *client)
SoupServerPrivate *priv = SOUP_SERVER_GET_PRIVATE (client->server);
priv->clients = g_slist_remove (priv->clients, client);
- g_signal_handlers_disconnect_by_func (sock, socket_disconnected, client);
- g_object_unref (sock);
+
+ if (client->msg) {
+ soup_message_set_status (client->msg, SOUP_STATUS_IO_ERROR);
+ soup_message_io_finished (client->msg);
+ }
}
static void
@@ -1463,10 +1448,8 @@ soup_server_accept_socket (SoupServer *server,
SoupServerPrivate *priv = SOUP_SERVER_GET_PRIVATE (server);
SoupClientContext *client;
- client = soup_client_context_new (server, g_object_ref (sock));
+ client = soup_client_context_new (server, sock);
priv->clients = g_slist_prepend (priv->clients, client);
- g_signal_connect (sock, "disconnected",
- G_CALLBACK (socket_disconnected), client);
start_request (server, client);
}
@@ -1514,6 +1497,7 @@ soup_server_accept_iostream (SoupServer *server,
return FALSE;
soup_server_accept_socket (server, sock);
+ g_object_unref (sock);
return TRUE;
}
@@ -1661,8 +1645,9 @@ void
soup_server_disconnect (SoupServer *server)
{
SoupServerPrivate *priv;
- GSList *listeners, *iter;
+ GSList *listeners, *clients, *iter;
SoupSocket *listener;
+ SoupClientContext *client;
g_return_if_fail (SOUP_IS_SERVER (server));
priv = SOUP_SERVER_GET_PRIVATE (server);
@@ -1673,8 +1658,17 @@ soup_server_disconnect (SoupServer *server)
G_GNUC_END_IGNORE_DEPRECATIONS;
}
+ clients = priv->clients;
+ priv->clients = NULL;
listeners = priv->listeners;
priv->listeners = NULL;
+
+ for (iter = clients; iter; iter = iter->next) {
+ client = iter->data;
+ soup_socket_disconnect (client->sock);
+ }
+ g_slist_free (clients);
+
for (iter = listeners; iter; iter = iter->next) {
listener = iter->data;
soup_socket_disconnect (listener);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]