libsoup r1119 - in trunk: . libsoup



Author: danw
Date: Fri Apr  4 00:58:38 2008
New Revision: 1119
URL: http://svn.gnome.org/viewvc/libsoup?rev=1119&view=rev

Log:
	Be more aggressive about closing unused persistent connections
	when needed, to avoid slow load times in WebKit.

	* libsoup/soup-session-async.c (run_queue): Remove the
	"try_pruning" flag from here and from all the callers, and
	*always* try pruning idle connections if it would help.

	* libsoup/soup-session.c (soup_session_try_prune_connection):
	Rather than only closing a single connection, close all idle
	connections.


Modified:
   trunk/ChangeLog
   trunk/libsoup/soup-session-async.c
   trunk/libsoup/soup-session.c

Modified: trunk/libsoup/soup-session-async.c
==============================================================================
--- trunk/libsoup/soup-session-async.c	(original)
+++ trunk/libsoup/soup-session-async.c	Fri Apr  4 00:58:38 2008
@@ -23,7 +23,8 @@
  * single-threaded programs.
  **/
 
-static gboolean run_queue (SoupSessionAsync *sa, gboolean try_pruning);
+static gboolean run_queue (SoupSessionAsync *sa);
+static void do_idle_run_queue (SoupSession *session);
 
 static void  queue_message   (SoupSession *session, SoupMessage *req,
 			      SoupSessionCallback callback, gpointer user_data);
@@ -85,12 +86,12 @@
 
 
 static void
-connection_closed (SoupConnection *conn, SoupSessionAsync *sa)
+connection_closed (SoupConnection *conn, gpointer session)
 {
 	/* Run the queue in case anyone was waiting for a connection
 	 * to be closed.
 	 */
-	run_queue (sa, FALSE);
+	do_idle_run_queue (session);
 }
 
 static void
@@ -109,7 +110,7 @@
 		 * queue that were waiting for the connection count
 		 * to go down, so run the queue now.
 		 */
-		run_queue (sa, FALSE);
+		run_queue (sa);
 		return;
 	}
 
@@ -125,24 +126,25 @@
 	 * idle pool and then just run the queue and see what happens.
 	 */
 	soup_connection_release (conn);
-	run_queue (sa, FALSE);
+	run_queue (sa);
 }
 
 static gboolean
-run_queue (SoupSessionAsync *sa, gboolean try_pruning)
+run_queue (SoupSessionAsync *sa)
 {
 	SoupSession *session = SOUP_SESSION (sa);
 	SoupMessageQueue *queue = soup_session_get_queue (session);
 	SoupMessageQueueIter iter;
 	SoupMessage *msg;
 	SoupConnection *conn;
-	gboolean should_prune = FALSE, started_any = FALSE, is_new;
+	gboolean try_pruning = TRUE, should_prune = FALSE;
+	gboolean started_any = FALSE, is_new;
 
 	/* FIXME: prefer CONNECTING messages */
 
  try_again:
 	for (msg = soup_message_queue_first (queue, &iter);
-	     msg;
+	     msg && !should_prune;
 	     msg = soup_message_queue_next (queue, &iter)) {
 
 		if (!SOUP_MESSAGE_IS_STARTING (msg) ||
@@ -159,15 +161,12 @@
 						       session);
 		} else
 			soup_connection_send_request (conn, msg);
-
-		started_any = TRUE;
 	}
 
-	if (try_pruning && should_prune && !started_any) {
-		/* We didn't manage to start any message, but there is
-		 * at least one message in the queue that could be
-		 * sent if we pruned an idle connection from some
-		 * other server.
+	if (try_pruning && should_prune) {
+		/* There is at least one message in the queue that
+		 * could be sent if we pruned an idle connection from
+		 * some other server.
 		 */
 		if (soup_session_try_prune_connection (session)) {
 			try_pruning = FALSE;
@@ -181,7 +180,7 @@
 static void
 request_restarted (SoupMessage *req, gpointer sa)
 {
-	run_queue (sa, FALSE);
+	run_queue (sa);
 }
 
 typedef struct {
@@ -212,7 +211,7 @@
 
 	if (sa) {
 		g_object_remove_weak_pointer (G_OBJECT (sa), (gpointer)&sa);
-		run_queue (sa, FALSE);
+		run_queue (sa);
 	}
 }
 
@@ -226,12 +225,19 @@
 
 	if (sa) {
 		g_object_remove_weak_pointer (G_OBJECT (sa), (gpointer)&sa);
-		run_queue (sa, TRUE);
+		run_queue (sa);
 	}
 	return FALSE;
 }
 
 static void
+do_idle_run_queue (SoupSession *session)
+{
+	soup_add_idle (soup_session_get_async_context (session),
+		       idle_run_queue, g_object_ref (session));
+}
+
+static void
 queue_message (SoupSession *session, SoupMessage *req,
 	       SoupSessionCallback callback, gpointer user_data)
 {
@@ -249,10 +255,7 @@
 				G_CALLBACK (final_finished), saqd);
 
 	SOUP_SESSION_CLASS (soup_session_async_parent_class)->queue_message (session, req, callback, user_data);
-
-	g_object_ref (sa);
-	soup_add_idle (soup_session_get_async_context (session),
-		       idle_run_queue, sa);
+	do_idle_run_queue (session);
 }
 
 static guint

Modified: trunk/libsoup/soup-session.c
==============================================================================
--- trunk/libsoup/soup-session.c	(original)
+++ trunk/libsoup/soup-session.c	Fri Apr  4 00:58:38 2008
@@ -808,55 +808,41 @@
 		       msg, soup_connection_get_socket (conn));
 }
 
-static void
-find_oldest_connection (gpointer key, gpointer host, gpointer data)
-{
-	SoupConnection *conn = key, **oldest = data;
-
-	/* Don't prune a connection that is currently in use, or
-	 * hasn't been used yet.
-	 */
-	if (soup_connection_is_in_use (conn) ||
-	    soup_connection_last_used (conn) == 0)
-		return;
-
-	if (!*oldest || (soup_connection_last_used (conn) <
-			 soup_connection_last_used (*oldest)))
-		*oldest = conn;
-}
-
-/**
- * soup_session_try_prune_connection:
- * @session: a #SoupSession
- *
- * Finds the least-recently-used idle connection in @session and closes
- * it.
- *
- * Return value: %TRUE if a connection was closed, %FALSE if there are
- * no idle connections.
- **/
 gboolean
 soup_session_try_prune_connection (SoupSession *session)
 {
 	SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
-	SoupConnection *oldest = NULL;
+	GPtrArray *conns;
+	GHashTableIter iter;
+	gpointer conn, host;
+	int i;
+
+	conns = g_ptr_array_new ();
 
 	g_mutex_lock (priv->host_lock);
-	g_hash_table_foreach (priv->conns, find_oldest_connection,
-			      &oldest);
-	if (oldest) {
-		/* Ref the connection before unlocking the mutex in
-		 * case someone else tries to prune it too.
+	g_hash_table_iter_init (&iter, priv->conns);
+	while (g_hash_table_iter_next (&iter, &conn, &host)) {
+		/* Don't prune a connection that is currently in use,
+		 * or hasn't been used yet.
 		 */
-		g_object_ref (oldest);
-		g_mutex_unlock (priv->host_lock);
-		soup_connection_disconnect (oldest);
-		g_object_unref (oldest);
-		return TRUE;
-	} else {
-		g_mutex_unlock (priv->host_lock);
+		if (!soup_connection_is_in_use (conn) &&
+		    soup_connection_last_used (conn) > 0)
+			g_ptr_array_add (conns, g_object_ref (conn));
+	}
+	g_mutex_unlock (priv->host_lock);
+
+	if (!conns->len) {
+		g_ptr_array_free (conns, TRUE);
 		return FALSE;
 	}
+
+	for (i = 0; i < conns->len; i++) {
+		soup_connection_disconnect (conns->pdata[i]);
+		g_object_unref (conns->pdata[i]);
+	}
+	g_ptr_array_free (conns, TRUE);
+
+	return TRUE;
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]