[libgdata] core: Add a “cancellable” property to GDataDownloadStream
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata] core: Add a “cancellable” property to GDataDownloadStream
- Date: Mon, 20 Dec 2010 13:49:09 +0000 (UTC)
commit 002d4d83e03f7bb30544d7690c83e4c44f5ae73f
Author: Philip Withnall <philip tecnocode co uk>
Date: Sat Dec 18 12:35:54 2010 +0000
core: Add a â??cancellableâ?? property to GDataDownloadStream
Allow the code which creates the GDataDownloadStream to specify a GCancellable
which will cancel the entire download operation (i.e. permanently cancel all
I/O on the stream and all network activity).
This breaks the following API:
â?¢ gdata_download_stream_new()
The following API has been added:
â?¢ GDataDownloadStream:cancellable
â?¢ gdata_download_stream_get_cancellable()
Helps: bgo#637036
docs/reference/gdata-sections.txt | 1 +
gdata/gdata-download-stream.c | 83 ++++++++++++++++----
gdata/gdata-download-stream.h | 4 +-
gdata/gdata.symbols | 1 +
gdata/media/gdata-media-content.c | 2 +-
gdata/media/gdata-media-thumbnail.c | 2 +-
.../services/documents/gdata-documents-document.c | 2 +-
7 files changed, 76 insertions(+), 19 deletions(-)
---
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index 43ffdc3..7490525 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -1753,6 +1753,7 @@ GDataDownloadStream
GDataDownloadStreamClass
gdata_download_stream_new
gdata_download_stream_get_service
+gdata_download_stream_get_cancellable
gdata_download_stream_get_download_uri
gdata_download_stream_get_content_type
gdata_download_stream_get_content_length
diff --git a/gdata/gdata-download-stream.c b/gdata/gdata-download-stream.c
index 72de537..e7083c6 100644
--- a/gdata/gdata-download-stream.c
+++ b/gdata/gdata-download-stream.c
@@ -97,7 +97,8 @@ enum {
PROP_SERVICE = 1,
PROP_DOWNLOAD_URI,
PROP_CONTENT_TYPE,
- PROP_CONTENT_LENGTH
+ PROP_CONTENT_LENGTH,
+ PROP_CANCELLABLE
};
G_DEFINE_TYPE_WITH_CODE (GDataDownloadStream, gdata_download_stream, G_TYPE_INPUT_STREAM,
@@ -181,6 +182,27 @@ gdata_download_stream_class_init (GDataDownloadStreamClass *klass)
"Content length", "The length (in bytes) of the file being downloaded.",
-1, G_MAXSSIZE, -1,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataDownloadStream:cancellable:
+ *
+ * An optional cancellable used to cancel the entire download operation. If a #GCancellable instance isn't provided for this property at
+ * construction time (i.e. to gdata_download_stream_new()), one will be created internally and can be retrieved using
+ * gdata_download_stream_get_cancellable() and used to cancel the download operation with g_cancellable_cancel() just as if it was passed to
+ * gdata_download_stream_new().
+ *
+ * If the download operation is cancelled using this #GCancellable, any ongoing network activity will be stopped, and any pending or future
+ * calls to #GInputStream API on the #GDataDownloadStream will return %G_IO_ERROR_CANCELLED. Note that the #GCancellable objects which can be
+ * passed to individual #GInputStream operations will not cancel the download operation proper if cancelled â?? they will merely cancel that API
+ * call. The only way to cancel the download operation completely is using #GDataDownloadStream:cancellable.
+ *
+ * Since: 0.8.0
+ **/
+ g_object_class_install_property (gobject_class, PROP_CANCELLABLE,
+ g_param_spec_object ("cancellable",
+ "Cancellable", "An optional cancellable used to cancel the entire download operation.",
+ G_TYPE_CANCELLABLE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
static void
@@ -218,6 +240,10 @@ gdata_download_stream_constructor (GType type, guint n_construct_params, GObject
object = G_OBJECT_CLASS (gdata_download_stream_parent_class)->constructor (type, n_construct_params, construct_params);
priv = GDATA_DOWNLOAD_STREAM (object)->priv;
+ /* Create a #GCancellable for the entire download operation if one wasn't specified for #GDataDownloadStream:cancellable during construction */
+ if (priv->cancellable == NULL)
+ priv->cancellable = g_cancellable_new ();
+
/* Build the message */
priv->message = soup_message_new (SOUP_METHOD_GET, priv->download_uri);
@@ -297,6 +323,9 @@ gdata_download_stream_get_property (GObject *object, guint property_id, GValue *
g_value_set_long (value, priv->content_length);
g_static_mutex_unlock (&(priv->content_mutex));
break;
+ case PROP_CANCELLABLE:
+ g_value_set_object (value, priv->cancellable);
+ break;
default:
/* We don't have any other property... */
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -317,6 +346,10 @@ gdata_download_stream_set_property (GObject *object, guint property_id, const GV
case PROP_DOWNLOAD_URI:
priv->download_uri = g_value_dup_string (value);
break;
+ case PROP_CANCELLABLE:
+ /* Construction only */
+ priv->cancellable = g_value_dup_object (value);
+ break;
default:
/* We don't have any other property... */
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -529,42 +562,44 @@ static void
create_network_thread (GDataDownloadStream *self, GError **error)
{
GDataDownloadStreamPrivate *priv = self->priv;
- GError *child_error = NULL;
- g_assert (priv->cancellable == NULL);
g_assert (priv->network_thread == NULL);
-
- priv->cancellable = g_cancellable_new ();
- priv->network_thread = g_thread_create ((GThreadFunc) download_thread, self, TRUE, &child_error);
-
- if (child_error != NULL) {
- g_object_unref (priv->cancellable);
- priv->cancellable = NULL;
- g_propagate_error (error, child_error);
- }
+ priv->network_thread = g_thread_create ((GThreadFunc) download_thread, self, TRUE, error);
}
/**
* gdata_download_stream_new:
* @service: a #GDataService
* @download_uri: the URI to download
+ * @cancellable: (allow-none): a #GCancellable for the entire download stream, or %NULL
*
* Creates a new #GDataDownloadStream, allowing a file to be downloaded from a GData service using standard #GInputStream API.
*
* As well as the standard GIO errors, calls to the #GInputStream API on a #GDataDownloadStream can also return any relevant specific error from
* #GDataServiceError, or %GDATA_SERVICE_ERROR_PROTOCOL_ERROR in the general case.
*
+ * If a #GCancellable is provided in @cancellable, the download operation may be cancelled at any time from another thread using g_cancellable_cancel().
+ * In this case, any ongoing network activity will be stopped, and any pending or future calls to #GInputStream API on the #GDataDownloadStream will
+ * return %G_IO_ERROR_CANCELLED. Note that the #GCancellable objects which can be passed to individual #GInputStream operations will not cancel the
+ * download operation proper if cancelled â?? they will merely cancel that API call. The only way to cancel the download operation completely is using
+ * this @cancellable.
+ *
* Return value: a new #GInputStream, or %NULL; unref with g_object_unref()
*
- * Since: 0.5.0
+ * Since: 0.8.0
**/
GInputStream *
-gdata_download_stream_new (GDataService *service, const gchar *download_uri)
+gdata_download_stream_new (GDataService *service, const gchar *download_uri, GCancellable *cancellable)
{
g_return_val_if_fail (GDATA_IS_SERVICE (service), NULL);
g_return_val_if_fail (download_uri != NULL, NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
- return G_INPUT_STREAM (g_object_new (GDATA_TYPE_DOWNLOAD_STREAM, "download-uri", download_uri, "service", service, NULL));
+ return G_INPUT_STREAM (g_object_new (GDATA_TYPE_DOWNLOAD_STREAM,
+ "download-uri", download_uri,
+ "service", service,
+ "cancellable", cancellable,
+ NULL));
}
/**
@@ -636,3 +671,21 @@ gdata_download_stream_get_content_length (GDataDownloadStream *self)
g_return_val_if_fail (GDATA_IS_DOWNLOAD_STREAM (self), -1);
return self->priv->content_length;
}
+
+/**
+ * gdata_download_stream_get_cancellable:
+ * @self: a #GDataDownloadStream
+ *
+ * Gets the #GCancellable for the entire download operation, #GDataDownloadStream:cancellable.
+ *
+ * Return value: (transfer none): the #GCancellable for the entire download operation
+ *
+ * Since: 0.8.0
+ **/
+GCancellable *
+gdata_download_stream_get_cancellable (GDataDownloadStream *self)
+{
+ g_return_val_if_fail (GDATA_IS_DOWNLOAD_STREAM (self), NULL);
+ g_assert (self->priv->cancellable != NULL);
+ return self->priv->cancellable;
+}
diff --git a/gdata/gdata-download-stream.h b/gdata/gdata-download-stream.h
index 1601858..fc4a70b 100644
--- a/gdata/gdata-download-stream.h
+++ b/gdata/gdata-download-stream.h
@@ -63,12 +63,14 @@ typedef struct {
GType gdata_download_stream_get_type (void) G_GNUC_CONST;
-GInputStream *gdata_download_stream_new (GDataService *service, const gchar *download_uri) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+GInputStream *gdata_download_stream_new (GDataService *service, const gchar *download_uri,
+ GCancellable *cancellable) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
GDataService *gdata_download_stream_get_service (GDataDownloadStream *self) G_GNUC_PURE;
const gchar *gdata_download_stream_get_download_uri (GDataDownloadStream *self) G_GNUC_PURE;
const gchar *gdata_download_stream_get_content_type (GDataDownloadStream *self) G_GNUC_PURE;
gssize gdata_download_stream_get_content_length (GDataDownloadStream *self) G_GNUC_PURE;
+GCancellable *gdata_download_stream_get_cancellable (GDataDownloadStream *self) G_GNUC_PURE;
G_END_DECLS
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index ec777a6..93c683b 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -863,3 +863,4 @@ gdata_contacts_contact_set_photo_finish
gdata_youtube_video_get_coordinates
gdata_youtube_video_set_coordinates
gdata_upload_stream_get_cancellable
+gdata_download_stream_get_cancellable
diff --git a/gdata/media/gdata-media-content.c b/gdata/media/gdata-media-content.c
index 7f720ee..a34caba 100644
--- a/gdata/media/gdata-media-content.c
+++ b/gdata/media/gdata-media-content.c
@@ -563,5 +563,5 @@ gdata_media_content_download (GDataMediaContent *self, GDataService *service, GE
/* Get the download URI and create a stream for it */
src_uri = gdata_media_content_get_uri (self);
- return GDATA_DOWNLOAD_STREAM (gdata_download_stream_new (service, src_uri));
+ return GDATA_DOWNLOAD_STREAM (gdata_download_stream_new (service, src_uri, NULL));
}
diff --git a/gdata/media/gdata-media-thumbnail.c b/gdata/media/gdata-media-thumbnail.c
index 6f59989..0133850 100644
--- a/gdata/media/gdata-media-thumbnail.c
+++ b/gdata/media/gdata-media-thumbnail.c
@@ -390,5 +390,5 @@ gdata_media_thumbnail_download (GDataMediaThumbnail *self, GDataService *service
/* Get the download URI and create a stream for it */
src_uri = gdata_media_thumbnail_get_uri (self);
- return GDATA_DOWNLOAD_STREAM (gdata_download_stream_new (service, src_uri));
+ return GDATA_DOWNLOAD_STREAM (gdata_download_stream_new (service, src_uri, NULL));
}
diff --git a/gdata/services/documents/gdata-documents-document.c b/gdata/services/documents/gdata-documents-document.c
index 4fd9b35..f2e62dd 100644
--- a/gdata/services/documents/gdata-documents-document.c
+++ b/gdata/services/documents/gdata-documents-document.c
@@ -115,7 +115,7 @@ gdata_documents_document_download (GDataDocumentsDocument *self, GDataDocumentsS
/* Get the download URI and create a stream for it */
download_uri = gdata_documents_document_get_download_uri (self, export_format);
- download_stream = GDATA_DOWNLOAD_STREAM (gdata_download_stream_new (_service, download_uri));
+ download_stream = GDATA_DOWNLOAD_STREAM (gdata_download_stream_new (_service, download_uri, NULL));
g_free (download_uri);
return download_stream;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]