[libsoup/new-io] add async support back to tests/get and fix some async bugs



commit 69f552d687b2fa0ae49565f363a4f7f101618d3c
Author: Dan Winship <danw gnome org>
Date:   Sun Dec 20 15:11:17 2009 +0100

    add async support back to tests/get and fix some async bugs

 libsoup/soup-ftp-connection.c |    5 ++-
 libsoup/soup-request-file.c   |   35 ++++++++++++--
 libsoup/soup-request-ftp.c    |   37 ++++++++++++--
 tests/get.c                   |  105 +++++++++++++++++++++++++++++++++--------
 4 files changed, 151 insertions(+), 31 deletions(-)
---
diff --git a/libsoup/soup-ftp-connection.c b/libsoup/soup-ftp-connection.c
index ece6e27..56b0b9b 100644
--- a/libsoup/soup-ftp-connection.c
+++ b/libsoup/soup-ftp-connection.c
@@ -536,6 +536,7 @@ ftp_connection_receive_reply_async_cb (GObject      *source_object,
 
 	simple = G_SIMPLE_ASYNC_RESULT (user_data);
 	ftp = SOUP_FTP_CONNECTION (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+	g_object_unref (ftp);
 	buffer = g_data_input_stream_read_line_finish (ftp->priv->control_input,
 						       read_res,
 						       &len,
@@ -679,7 +680,7 @@ ftp_connection_send_command_cb (GObject      *source_object,
 	g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (user_data));
 
 	simple = G_SIMPLE_ASYNC_RESULT (user_data);
-	ftp = SOUP_FTP_CONNECTION (g_async_result_get_source_object (result));
+	ftp = SOUP_FTP_CONNECTION (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
 	g_object_unref (ftp);
 	bytes_to_write = g_simple_async_result_get_op_res_gssize (simple);
 	bytes_written = g_output_stream_write_finish (G_OUTPUT_STREAM (source_object),
@@ -1504,6 +1505,7 @@ ftp_connection_connection_cb (GObject      *source_object,
 	client = G_SOCKET_CLIENT (source_object);
 	simple = G_SIMPLE_ASYNC_RESULT (user_data);
 	ftp = SOUP_FTP_CONNECTION (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+	g_object_unref (ftp);
 	ftp->priv->control = g_socket_client_connect_to_host_finish (client,
 								result,
 								&error);
@@ -1720,6 +1722,7 @@ ftp_callback_data (GObject      *source_object,
 	simple = G_SIMPLE_ASYNC_RESULT (user_data);
 	client = G_SOCKET_CLIENT (source_object);
 	ftp = SOUP_FTP_CONNECTION (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+	g_object_unref (ftp);
 	ftp->priv->data = g_socket_client_connect_finish (client,
 							res,
 							&error);
diff --git a/libsoup/soup-request-file.c b/libsoup/soup-request-file.c
index 7acac68..351be14 100644
--- a/libsoup/soup-request-file.c
+++ b/libsoup/soup-request-file.c
@@ -116,15 +116,38 @@ soup_request_file_send (SoupRequest          *request,
 }
 
 static void
+sent_async (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+	GFile *gfile = G_FILE (source);
+	GSimpleAsyncResult *simple = user_data;
+	GError *error = NULL;
+	GFileInputStream *istream;
+
+	istream = g_file_read_finish (gfile, result, &error);
+	if (istream)
+		g_simple_async_result_set_op_res_gpointer (simple, istream, g_object_unref);
+	else {
+		g_simple_async_result_set_from_error (simple, error);
+		g_error_free (error);
+	}
+	g_simple_async_result_complete (simple);
+	g_object_unref (simple);
+}
+
+static void
 soup_request_file_send_async (SoupRequest          *request,
 			      GCancellable         *cancellable,
 			      GAsyncReadyCallback   callback,
 			      gpointer              user_data)
 {
 	SoupRequestFile *file = SOUP_REQUEST_FILE (request);
+	GSimpleAsyncResult *simple;
 
+	simple = g_simple_async_result_new (G_OBJECT (request),
+					    callback, user_data,
+					    soup_request_file_send_async);
 	g_file_read_async (file->priv->gfile, G_PRIORITY_DEFAULT,
-			   cancellable, callback, user_data);
+			   cancellable, sent_async, simple);
 }
 
 static GInputStream *
@@ -132,8 +155,12 @@ soup_request_file_send_finish (SoupRequest          *request,
 			       GAsyncResult         *result,
 			       GError              **error)
 {
-	SoupRequestFile *file = SOUP_REQUEST_FILE (request);
+	GSimpleAsyncResult *simple;
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (request), soup_request_file_send_async), NULL);
 
-	return (GInputStream *)g_file_read_finish (file->priv->gfile,
-						   result, error);
+	simple = G_SIMPLE_ASYNC_RESULT (result);
+	if (g_simple_async_result_propagate_error (simple, error))
+		return NULL;
+	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
 }
diff --git a/libsoup/soup-request-ftp.c b/libsoup/soup-request-ftp.c
index 7b1a741..a81872d 100644
--- a/libsoup/soup-request-ftp.c
+++ b/libsoup/soup-request-ftp.c
@@ -108,18 +108,40 @@ soup_request_ftp_send (SoupRequest          *request,
 }
 
 static void
+sent_async (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+	SoupFTPConnection *ftp = SOUP_FTP_CONNECTION (source);
+	GSimpleAsyncResult *simple = user_data;
+	GError *error = NULL;
+	GInputStream *istream;
+
+	istream = soup_ftp_connection_load_uri_finish (ftp, result, &error);
+	if (istream)
+		g_simple_async_result_set_op_res_gpointer (simple, istream, g_object_unref);
+	else {
+		g_simple_async_result_set_from_error (simple, error);
+		g_error_free (error);
+	}
+	g_simple_async_result_complete (simple);
+	g_object_unref (simple);
+}
+
+static void
 soup_request_ftp_send_async (SoupRequest          *request,
 			     GCancellable         *cancellable,
 			     GAsyncReadyCallback   callback,
 			     gpointer              user_data)
 {
 	SoupRequestFtp *ftp = SOUP_REQUEST_FTP (request);
+	GSimpleAsyncResult *simple;
 
+	simple = g_simple_async_result_new (G_OBJECT (request),
+					    callback, user_data,
+					    soup_request_ftp_send_async);
 	soup_ftp_connection_load_uri_async (ftp->priv->conn,
 					    soup_request_base_get_uri (SOUP_REQUEST_BASE (request)),
 					    cancellable,
-					    callback,
-					    user_data);
+					    sent_async, simple);
 }
 
 static GInputStream *
@@ -127,9 +149,12 @@ soup_request_ftp_send_finish (SoupRequest          *request,
 			      GAsyncResult         *result,
 			      GError              **error)
 {
-	SoupRequestFtp *ftp = SOUP_REQUEST_FTP (request);
+	GSimpleAsyncResult *simple;
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (request), soup_request_ftp_send_async), NULL);
 
-	return soup_ftp_connection_load_uri_finish (ftp->priv->conn,
-						    result,
-						    error);
+	simple = G_SIMPLE_ASYNC_RESULT (result);
+	if (g_simple_async_result_propagate_error (simple, error))
+		return NULL;
+	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
 }
diff --git a/tests/get.c b/tests/get.c
index 188543b..6568f0a 100644
--- a/tests/get.c
+++ b/tests/get.c
@@ -22,25 +22,17 @@
 #include <libsoup/soup.h>
 #endif
 
-static SoupSession *session;
+GMainLoop *loop;
 static gboolean debug = FALSE, quiet = FALSE;
+static char buf[8192];
 
 static void
-get_url (SoupURI *uri)
+get_url_sync (SoupRequest *req)
 {
-	SoupRequest *req;
 	GInputStream *istream;
 	GError *error = NULL;
-	char buf[8192];
 	gsize nread;
 
-	req = soup_session_request_uri (session, uri, &error);
-	if (!req) {
-		fprintf (stderr, "Could not request URI: %s\n",
-			 error->message);
-		exit (1);
-	}
-
 	istream = soup_request_send (req, NULL, &error);
 	if (!istream) {
 		fprintf (stderr, "Could not send URI: %s\n",
@@ -59,18 +51,73 @@ get_url (SoupURI *uri)
 }
 
 static void
+did_read_async (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+	GInputStream *istream = G_INPUT_STREAM (source);
+	gsize nread;
+	GError *error = NULL;
+
+	nread = g_input_stream_read_finish (istream, result, &error);
+
+	if (nread == 0)
+		g_main_loop_quit (loop);
+	else if (nread < 0) {
+		fprintf (stderr, "Read failed: %s\n", error->message);
+		exit (1);
+	}
+
+	fwrite (buf, 1, nread, stdout);
+	g_input_stream_read_async (istream, buf, sizeof (buf),
+				   G_PRIORITY_DEFAULT, NULL,
+				   did_read_async, NULL);
+}
+
+static void
+sent_url_async (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+	SoupRequest *request = SOUP_REQUEST (source);
+	GInputStream *istream;
+	GError *error = NULL;
+
+	istream = soup_request_send_finish (request, result, &error);
+	if (!istream) {
+		fprintf (stderr, "Could not send URI: %s\n",
+			 error->message);
+		exit (1);
+	}
+
+	g_input_stream_read_async (istream, buf, sizeof (buf),
+				   G_PRIORITY_DEFAULT, NULL,
+				   did_read_async, NULL);
+}
+
+static void
+get_url_async (SoupRequest *req)
+{
+	loop = g_main_loop_new (NULL, TRUE);
+
+	soup_request_send_async (req, NULL, sent_url_async, NULL);
+
+	g_main_loop_run (loop);
+}
+
+static void
 usage (void)
 {
-	fprintf (stderr, "Usage: get [-p proxy] [-d] URL\n");
+	fprintf (stderr, "Usage: get [-p proxy] [-d] [-s] URL\n");
 	exit (1);
 }
 
 int
 main (int argc, char **argv)
 {
+	SoupSession *session;
+	SoupRequest *req;
 	const char *url;
 	SoupURI *proxy = NULL, *parsed;
+	gboolean sync = FALSE;
 	int opt;
+	GError *error = NULL;
 
 	g_thread_init (NULL);
 	g_type_init ();
@@ -94,6 +141,10 @@ main (int argc, char **argv)
 			quiet = TRUE;
 			break;
 
+		case 's':
+			sync = TRUE;
+			break;
+
 		case '?':
 			usage ();
 			break;
@@ -111,15 +162,15 @@ main (int argc, char **argv)
 		exit (1);
 	}
 
-	session = soup_session_sync_new_with_options (
+	session = g_object_new (sync ? SOUP_TYPE_SESSION_SYNC : SOUP_TYPE_SESSION_ASYNC,
 #ifdef HAVE_GNOME
-		SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
+				SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
 #endif
-		SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_DECODER,
-		SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_COOKIE_JAR,
-		SOUP_SESSION_USER_AGENT, "get ",
-		SOUP_SESSION_ACCEPT_LANGUAGE_AUTO, TRUE,
-		NULL);
+				SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_DECODER,
+				SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_COOKIE_JAR,
+				SOUP_SESSION_USER_AGENT, "get ",
+				SOUP_SESSION_ACCEPT_LANGUAGE_AUTO, TRUE,
+				NULL);
 
 	/* Need to do this after creating the session, since adding
 	 * SOUP_TYPE_GNOME_FEATURE_2_26 will add a proxy resolver, thereby
@@ -131,7 +182,21 @@ main (int argc, char **argv)
 			      NULL);
 	}
 
-	get_url (parsed);
+	req = soup_session_request_uri (session, parsed, &error);
+	g_object_unref (session);
 	soup_uri_free (parsed);
+
+	if (!req) {
+		fprintf (stderr, "Could not request URI: %s\n",
+			 error->message);
+		exit (1);
+	}
+
+	if (sync)
+		get_url_sync (req);
+	else
+		get_url_async (req);
+
+	g_object_unref (req);
 	return 0;
 }



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