[libgdata] Bug 635959 — Proper cancellation support for GDataUploadStream



commit acf599f253512bced955e5fa94528c82dac79f82
Author: Philip Withnall <philip tecnocode co uk>
Date:   Tue Nov 30 23:56:18 2010 +0000

    Bug 635959 â?? Proper cancellation support for GDataUploadStream
    
    Add proper cancellation support to GDataUploadStream. This involves adding
    support for not starting the upload thread if the operation has been
    cancelled very early, plus adding support for cancelling it mid-upload using
    soup_session_cancel_message().
    
    One of the PicasaWeb upload cancellation tests had to be changed to use a
    smaller timeout in order to provide more of a guarantee that it'll cancel
    during the upload.
    
    Closes: bgo#635959

 gdata/gdata-upload-stream.c |   25 +++++++++++++++++++++++--
 gdata/tests/picasaweb.c     |    2 +-
 2 files changed, 24 insertions(+), 3 deletions(-)
---
diff --git a/gdata/gdata-upload-stream.c b/gdata/gdata-upload-stream.c
index bde40d6..084b016 100644
--- a/gdata/gdata-upload-stream.c
+++ b/gdata/gdata-upload-stream.c
@@ -295,7 +295,8 @@ gdata_upload_stream_finalize (GObject *object)
 {
 	GDataUploadStreamPrivate *priv = GDATA_UPLOAD_STREAM (object)->priv;
 
-	g_thread_join (priv->network_thread);
+	if (priv->network_thread != NULL)
+		g_thread_join (priv->network_thread);
 	g_static_mutex_free (&(priv->response_mutex));
 	g_cond_free (priv->finished_cond);
 	g_cond_free (priv->write_cond);
@@ -378,6 +379,9 @@ write_cancelled_cb (GCancellable *cancellable, GDataUploadStream *self)
 {
 	GDataUploadStreamPrivate *priv = self->priv;
 
+	/* Tell libsoup to cancel the upload */
+	soup_session_cancel_message (priv->session, priv->message, SOUP_STATUS_CANCELLED);
+
 	/* Set the error and signal that the write operation has finished */
 	g_static_mutex_lock (&(priv->write_mutex));
 
@@ -402,6 +406,20 @@ gdata_upload_stream_write (GOutputStream *stream, const void *buffer, gsize coun
 	if (cancellable != NULL)
 		cancelled_signal = g_cancellable_connect (cancellable, (GCallback) write_cancelled_cb, GDATA_UPLOAD_STREAM (stream), NULL);
 
+	/* Check for an error and return if necessary */
+	g_static_mutex_lock (&(priv->response_mutex));
+	if (priv->response_error != NULL) {
+		g_propagate_error (error, priv->response_error);
+		priv->response_error = NULL;
+		g_static_mutex_unlock (&(priv->response_mutex));
+
+		if (cancellable != NULL)
+			g_cancellable_disconnect (cancellable, cancelled_signal);
+
+		return -1;
+	}
+	g_static_mutex_unlock (&(priv->response_mutex));
+
 	/* Set write_finished so we know if the write operation has finished before we reach write_cond */
 	priv->write_finished = FALSE;
 
@@ -525,7 +543,10 @@ gdata_upload_stream_close (GOutputStream *stream, GCancellable *cancellable, GEr
 			cancelled_signal = g_cancellable_connect (cancellable, (GCallback) close_cancelled_cb, GDATA_UPLOAD_STREAM (stream), NULL);
 
 		/* Wait for the signal that we've finished */
-		g_cond_wait (priv->finished_cond, g_static_mutex_get_mutex (&(priv->response_mutex)));
+		if (g_cancellable_is_cancelled (cancellable))
+			priv->response_status = SOUP_STATUS_CANCELLED;
+		else if (priv->network_thread != NULL)
+			g_cond_wait (priv->finished_cond, g_static_mutex_get_mutex (&(priv->response_mutex)));
 
 		/* Disconnect from the signal handler so we can't receive any more cancellation events before we handle errors*/
 		if (cancellable != NULL)
diff --git a/gdata/tests/picasaweb.c b/gdata/tests/picasaweb.c
index 932f203..849cbf9 100644
--- a/gdata/tests/picasaweb.c
+++ b/gdata/tests/picasaweb.c
@@ -694,7 +694,7 @@ test_upload_cancellation2 (gconstpointer service)
 	/* Create a main loop and an idle function which will cancel the upload */
 	main_loop = g_main_loop_new (NULL, TRUE);
 	cancellable = g_cancellable_new ();
-	g_timeout_add (10, (GSourceFunc) test_upload_cancellation_cancel_cb, cancellable);
+	g_timeout_add (1, (GSourceFunc) test_upload_cancellation_cancel_cb, cancellable);
 
 	/* Upload the photo */
 	gdata_picasaweb_service_upload_file_async (GDATA_PICASAWEB_SERVICE (service), NULL, photo, photo_file, cancellable,



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