[libsoup] misc-test: fix up the new persistent connection timeout test



commit 81d74479a5a15bed369dc0a2e677742f72686cc5
Author: Dan Winship <danw gnome org>
Date:   Thu Nov 18 10:15:28 2010 -0500

    misc-test: fix up the new persistent connection timeout test
    
    The original version of the test implicitly depended on thread
    scheduling, and would fail if the server thread didn't get a chance to
    run after returning its response but before the the client thread made
    its next request. Fix that.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=631525

 tests/misc-test.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 48 insertions(+), 5 deletions(-)
---
diff --git a/tests/misc-test.c b/tests/misc-test.c
index 33b7bec..71263ee 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -49,6 +49,53 @@ timeout_socket (SoupSocket *sock, gpointer user_data)
 }
 
 static void
+timeout_request_started (SoupServer *server, SoupMessage *msg,
+			 SoupClientContext *client, gpointer user_data)
+{
+	SoupSocket *sock;
+	GMainContext *context = soup_server_get_async_context (server);
+	guint readable;
+
+	sock = soup_client_context_get_socket (client);
+	readable = g_signal_connect (sock, "readable",
+				    G_CALLBACK (timeout_socket), NULL);
+	while (soup_socket_is_connected (sock))
+		g_main_context_iteration (context, TRUE);
+	g_signal_handler_disconnect (sock, readable);
+	g_signal_handlers_disconnect_by_func (server, timeout_request_started, NULL);
+}
+
+static void
+setup_timeout_persistent (SoupServer *server, SoupSocket *sock)
+{
+	char buf[1];
+	gsize nread;
+
+	/* In order for the test to work correctly, we have to
+	 * close the connection *after* the client side writes
+	 * the request. To ensure that this happens reliably,
+	 * regardless of thread scheduling, we:
+	 *
+	 *   1. Try to read off the socket now, knowing it will
+	 *      fail (since the client is waiting for us to
+	 *      return a response). This will cause it to
+	 *      emit "readable" later.
+	 *   2. Connect to the server's request-started signal.
+	 *   3. Run an inner main loop from that signal handler
+	 *      until the socket emits "readable". (If we don't
+	 *      do this then it's possible the client's next
+	 *      request would be ready before we returned to
+	 *      the main loop, and so the signal would never be
+	 *      emitted.)
+	 *   4. Close the socket.
+	 */
+
+	soup_socket_read (sock, buf, 1, &nread, NULL, NULL);
+	g_signal_connect (server, "request-started",
+			  G_CALLBACK (timeout_request_started), NULL);
+}
+
+static void
 server_callback (SoupServer *server, SoupMessage *msg,
 		 const char *path, GHashTable *query,
 		 SoupClientContext *context, gpointer data)
@@ -119,12 +166,8 @@ server_callback (SoupServer *server, SoupMessage *msg,
 	if (!strcmp (path, "/timeout-persistent")) {
 		SoupSocket *sock;
 
-		/* We time out the persistent connection as soon as
-		 * the client starts writing the next request.
-		 */
 		sock = soup_client_context_get_socket (context);
-		g_signal_connect (sock, "readable",
-				  G_CALLBACK (timeout_socket), NULL);
+		setup_timeout_persistent (server, sock);
 	}
 
 	soup_message_set_status (msg, SOUP_STATUS_OK);



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