diff options
author | Iago Toral <itoral@igalia.com> | 2010-02-18 11:08:45 +0100 |
---|---|---|
committer | Iago Toral <itoral@igalia.com> | 2010-02-18 11:08:45 +0100 |
commit | 6d70e95f999153a5f3586019804dec7560680df8 (patch) | |
tree | e075b42ba6e2f37debf1c499b2027034505766f9 | |
parent | c736cf9c7fb3192718e556baa5332a1238dcb7e3 (diff) | |
download | grilo-plugins-6d70e95f999153a5f3586019804dec7560680df8.tar.gz |
[podcasts] Use the idle loop to avoid blocking when parsing feeds.
-rw-r--r-- | src/podcasts/grl-podcasts.c | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/src/podcasts/grl-podcasts.c b/src/podcasts/grl-podcasts.c index f735160..96fe90e 100644 --- a/src/podcasts/grl-podcasts.c +++ b/src/podcasts/grl-podcasts.c @@ -191,6 +191,12 @@ typedef struct { gpointer user_data; } OperationSpec; +typedef struct { + OperationSpec *os; + xmlDocPtr doc; + xmlNodePtr node; +} OperationSpecParse; + static GrlPodcastsSource *grl_podcasts_source_new (void); static void grl_podcasts_source_finalize (GObject *plugin); @@ -812,6 +818,43 @@ touch_podcast (sqlite3 *db, const gchar *podcast_id) } } +static gboolean +parse_entry_idle (gpointer user_data) +{ + OperationSpecParse *osp = (OperationSpecParse *) user_data; + + while (osp->node && xmlStrcmp (osp->node->name, (const xmlChar *) "item")) { + osp->node = osp->node->next; + } + + if (osp->node) { + Entry *entry = g_new0 (Entry, 1); + parse_entry (osp->doc, osp->node, entry); + if (0) print_entry (entry); + store_stream (GRL_PODCASTS_SOURCE (osp->os->source)->priv->db, + osp->os->media_id, entry); + free_entry (entry); + osp->node = osp->node->next; + } + + if (!osp->node) { + /* We are done parsing */ + + /* Update the last_refreshed date of the podcast */ + touch_podcast (GRL_PODCASTS_SOURCE (osp->os->source)->priv->db, + osp->os->media_id); + + /* Now that we have parsed the feed and stored the contents, let's + resolve the user's query */ + produce_podcast_contents_from_db (osp->os); + + g_free (osp->os); + xmlFreeDoc (osp->doc); + } + + return osp->node != NULL; +} + static void parse_feed (OperationSpec *os, const gchar *str, GError **error) { @@ -879,28 +922,13 @@ parse_feed (OperationSpec *os, const gchar *str, GError **error) goto free_resources; } - /* Then we parse the feed and store the streams */ - do { - while (node && xmlStrcmp (node->name, (const xmlChar *) "item")) { - node = node->next; - } - if (node) { - Entry *entry = g_new0 (Entry, 1); - parse_entry (doc, node, entry); - if (0) print_entry (entry); - store_stream (GRL_PODCASTS_SOURCE (os->source)->priv->db, - os->media_id, entry); - free_entry (entry); - node = node->next; - } - } while (node); - - /* We also update the last_refreshed date of the podcast */ - touch_podcast (GRL_PODCASTS_SOURCE (os->source)->priv->db, os->media_id); - - /* Now that we have parsed the feed and stored the contents, let's - resolve the user's query */ - produce_podcast_contents_from_db (os); + /* Then we produce items using the idle loop to prevent blocking */ + OperationSpecParse *osp = g_new0 (OperationSpecParse, 1); + osp->os = os; + osp->doc = doc; + osp->node = node; + g_idle_add (parse_entry_idle, osp); + return; free_resources: xmlFreeDoc (doc); @@ -930,8 +958,8 @@ read_feed_cb (gchar *xmldata, gpointer user_data) os->user_data, error); g_error_free (error); + g_free (os); } - g_free (os); } static void |