[PATCH 1/5] youtube: Make search() a cancellable operation
- From: "Juan A. Suarez Romero" <jasuarez igalia com>
- To: grilo-list gnome org
- Subject: [PATCH 1/5] youtube: Make search() a cancellable operation
- Date: Fri, 15 Apr 2011 09:55:11 +0200
Signed-off-by: Juan A. Suarez Romero <jasuarez igalia com>
---
src/media/youtube/grl-youtube.c | 73 +++++++++++++++++++++++++++++++++++----
1 files changed, 66 insertions(+), 7 deletions(-)
diff --git a/src/media/youtube/grl-youtube.c b/src/media/youtube/grl-youtube.c
index 3e8fca3..0044812 100644
--- a/src/media/youtube/grl-youtube.c
+++ b/src/media/youtube/grl-youtube.c
@@ -128,6 +128,7 @@ typedef struct {
typedef struct {
GrlMediaSource *source;
+ GCancellable *cancellable;
guint operation_id;
const gchar *container_id;
GList *keys;
@@ -156,6 +157,7 @@ typedef struct {
typedef struct {
GrlMedia *media;
+ GCancellable *cancellable;
BuildMediaFromEntryCbFunc callback;
gpointer user_data;
} SetMediaUrlAsyncReadCb;
@@ -209,6 +211,9 @@ static gboolean grl_youtube_test_media_from_uri (GrlMediaSource *source,
static void grl_youtube_get_media_from_uri (GrlMediaSource *source,
GrlMediaSourceMediaFromUriSpec *mfus);
+static void grl_youtube_source_cancel (GrlMetadataSource *source,
+ guint operation_id);
+
static void build_directories (GDataService *service);
static void compute_feed_counts (GDataService *service);
static void compute_category_counts (GDataService *service);
@@ -349,6 +354,7 @@ grl_youtube_source_class_init (GrlYoutubeSourceClass * klass)
source_class->media_from_uri = grl_youtube_get_media_from_uri;
metadata_class->supported_keys = grl_youtube_source_supported_keys;
metadata_class->slow_keys = grl_youtube_source_slow_keys;
+ metadata_class->cancel = grl_youtube_source_cancel;
gobject_class->set_property = grl_youtube_source_set_property;
gobject_class->finalize = grl_youtube_source_finalize;
@@ -422,6 +428,9 @@ operation_spec_unref (OperationSpec *os)
{
os->ref_count--;
if (os->ref_count == 0) {
+ if (os->cancellable) {
+ g_object_unref (os->cancellable);
+ }
g_slice_free (OperationSpec, os);
GRL_DEBUG ("freeing spec");
}
@@ -458,7 +467,9 @@ read_done_cb (GObject *source_object,
NULL,
&wc_error);
if (wc_error) {
- GRL_WARNING ("Failed to open '%s': %s", arc->url, wc_error->message);
+ if (wc_error->code != GRL_NET_WC_ERROR_CANCELLED) {
+ GRL_WARNING ("Failed to open '%s': %s", arc->url, wc_error->message);
+ }
arc->callback (NULL, arc->user_data);
g_error_free (wc_error);
} else {
@@ -470,6 +481,7 @@ read_done_cb (GObject *source_object,
static void
read_url_async (const gchar *url,
+ GCancellable *cancellable,
AsyncReadCbFunc callback,
gpointer user_data)
{
@@ -483,7 +495,7 @@ read_url_async (const gchar *url,
GRL_DEBUG ("Opening async '%s'", url);
grl_net_wc_request_async (get_wc (),
url,
- NULL,
+ cancellable,
read_done_cb,
arc);
}
@@ -559,6 +571,7 @@ set_media_url_async_read_cb (gchar *data, gpointer user_data)
static void
set_media_url (GrlMedia *media,
+ GCancellable *cancellable,
BuildMediaFromEntryCbFunc callback,
gpointer user_data)
{
@@ -583,10 +596,12 @@ set_media_url (GrlMedia *media,
set_media_url_async_read_data = g_new0 (SetMediaUrlAsyncReadCb, 1);
set_media_url_async_read_data->media = media;
+ set_media_url_async_read_data->cancellable = cancellable;
set_media_url_async_read_data->callback = callback;
set_media_url_async_read_data->user_data = user_data;
read_url_async (video_info_url,
+ cancellable,
set_media_url_async_read_cb,
set_media_url_async_read_data);
@@ -596,6 +611,7 @@ set_media_url (GrlMedia *media,
static void
build_media_from_entry (GrlMedia *content,
GDataEntry *entry,
+ GCancellable *cancellable,
const GList *keys,
BuildMediaFromEntryCbFunc callback,
gpointer user_data)
@@ -682,7 +698,7 @@ build_media_from_entry (GrlMedia *content,
if (need_url) {
/* URL resolution is async */
- set_media_url (media, callback, user_data);
+ set_media_url (media, cancellable, callback, user_data);
} else {
callback (media, user_data);
}
@@ -910,6 +926,12 @@ build_media_from_entry_search_cb (GrlMedia *media, gpointer user_data)
OperationSpec *os = (OperationSpec *) user_data;
guint remaining;
+ if (g_cancellable_is_cancelled (os->cancellable)) {
+ GRL_DEBUG ("%s: cancelled", __FUNCTION__);
+ operation_spec_unref (os);
+ return;
+ }
+
if (os->emitted < os->count) {
remaining = os->count - os->emitted - 1;
os->callback (os->source,
@@ -934,6 +956,7 @@ build_directories (GDataService *service)
/* Parse category list from Youtube and compute category counts */
read_url_async (YOUTUBE_CATEGORIES_URL,
+ NULL,
build_categories_directory_read_cb,
service);
@@ -969,7 +992,7 @@ metadata_cb (GObject *object,
ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
g_error_free (error);
} else {
- build_media_from_entry (ms->media, video, ms->keys,
+ build_media_from_entry (ms->media, video, NULL, ms->keys,
build_media_from_entry_metadata_cb, ms);
}
@@ -985,13 +1008,21 @@ search_progress_cb (GDataEntry *entry,
gpointer user_data)
{
OperationSpec *os = (OperationSpec *) user_data;
+
+ /* Check if operation has been cancelled */
+ if (g_cancellable_is_cancelled (os->cancellable)) {
+ GRL_DEBUG ("%s: cancelled", __FUNCTION__);
+ build_media_from_entry_search_cb (NULL, os);
+ return;
+ }
+
if (index < count) {
/* Keep track of the items we got here. Due to the asynchronous
* nature of build_media_from_entry(), when search_cb is invoked
* we have to check if we got as many results as we requested or
* not, and handle that situation properly */
os->matches++;
- build_media_from_entry (NULL, entry, os->keys,
+ build_media_from_entry (NULL, entry, os->cancellable, os->keys,
build_media_from_entry_search_cb, os);
} else {
GRL_WARNING ("Invalid index/count received grom libgdata, ignoring result");
@@ -1010,6 +1041,14 @@ search_cb (GObject *object, GAsyncResult *result, OperationSpec *os)
gboolean need_extra_unref = FALSE;
GrlYoutubeSource *source = GRL_YOUTUBE_SOURCE (os->source);
+ /* Check if operation was cancelled */
+ if (g_cancellable_is_cancelled (os->cancellable)) {
+ GRL_DEBUG ("Search operation has been cancelled");
+ os->callback (os->source, os->operation_id, NULL, 0, os->user_data, NULL);
+ operation_spec_unref (os);
+ return;
+ }
+
feed = gdata_service_query_finish (source->priv->service, result, &error);
if (!error && feed) {
/* If we are browsing a category, update the count for it */
@@ -1359,7 +1398,7 @@ media_from_uri_cb (GObject *object, GAsyncResult *result, gpointer user_data)
mfus->callback (mfus->source, mfus->media_from_uri_id, NULL, mfus->user_data, error);
g_error_free (error);
} else {
- build_media_from_entry (NULL, video, mfus->keys,
+ build_media_from_entry (NULL, video, NULL, mfus->keys,
build_media_from_entry_media_from_uri_cb,
mfus);
}
@@ -1416,6 +1455,7 @@ grl_youtube_source_search (GrlMediaSource *source,
os = operation_spec_new ();
os->source = source;
+ os->cancellable = g_cancellable_new ();
os->operation_id = ss->search_id;
os->keys = ss->keys;
os->skip = ss->skip + 1;
@@ -1427,10 +1467,14 @@ grl_youtube_source_search (GrlMediaSource *source,
/* Look for OPERATION_SPEC_REF_RATIONALE for details */
operation_spec_ref (os);
+ grl_metadata_source_set_operation_data (GRL_METADATA_SOURCE (source),
+ ss->search_id,
+ os);
+
query = gdata_query_new_with_limits (ss->text, os->skip, os->count);
gdata_youtube_service_query_videos_async (GDATA_YOUTUBE_SERVICE (GRL_YOUTUBE_SOURCE (source)->priv->service),
query,
- NULL,
+ os->cancellable,
search_progress_cb,
os,
(GAsyncReadyCallback) search_cb,
@@ -1626,3 +1670,18 @@ grl_youtube_get_media_from_uri (GrlMediaSource *source,
mfus);
#endif
}
+
+static void
+grl_youtube_source_cancel (GrlMetadataSource *source,
+ guint operation_id)
+{
+ GRL_DEBUG (__FUNCTION__);
+
+ OperationSpec *os =
+ (OperationSpec *) grl_metadata_source_get_operation_data (source,
+ operation_id);
+
+ if (os && os->cancellable) {
+ g_cancellable_cancel (os->cancellable);
+ }
+}
--
1.7.4.1
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]