diff -Nru totem-3.6.3/debian/changelog totem-3.6.3/debian/changelog --- totem-3.6.3/debian/changelog 2013-02-27 10:11:35.000000000 -0500 +++ totem-3.6.3/debian/changelog 2013-03-11 13:45:27.000000000 -0400 @@ -1,3 +1,11 @@ +totem (3.6.3-0ubuntu4) UNRELEASED; urgency=low + + * Apply git_refactor_async_chapters_loading patch + - upstream fix for totem crashed with SIGSEGV in g_data_set_internal() + (lp: #1100937) + + -- Doug McMahon Mon, 11 Mar 2013 13:09:07 -0400 + totem (3.6.3-0ubuntu3) raring; urgency=low * Add missing epochs on libxrandr and libxxf86vm build-dependencies. diff -Nru totem-3.6.3/debian/patches/git_refactor_async_chapters_loading.patch totem-3.6.3/debian/patches/git_refactor_async_chapters_loading.patch --- totem-3.6.3/debian/patches/git_refactor_async_chapters_loading.patch 1969-12-31 19:00:00.000000000 -0500 +++ totem-3.6.3/debian/patches/git_refactor_async_chapters_loading.patch 2013-03-11 13:39:21.000000000 -0400 @@ -0,0 +1,319 @@ +From da0961f0f5d6221a13e9201436d84c423c811c87 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Wed, 06 Mar 2013 12:31:48 +0000 +Subject: chapters: Refactor async chapters loading + +Using GIO-style async functions which can be properly cancelled. + +https://bugzilla.gnome.org/show_bug.cgi?id=692731 +--- +diff --git a/src/plugins/chapters/totem-chapters.c b/src/plugins/chapters/totem-chapters.c +index dfffc89..dec42c7 100644 +--- a/src/plugins/chapters/totem-chapters.c ++++ b/src/plugins/chapters/totem-chapters.c +@@ -98,7 +98,7 @@ enum { + }; + + static void totem_file_opened_async_cb (TotemObject *totem, const gchar *uri, TotemChaptersPlugin *plugin); +-static void totem_file_opened_result_cb (gpointer data, gpointer user_data); ++static void totem_file_opened_result_cb (GObject *source_object, GAsyncResult *res, gpointer user_data); + static void totem_file_closed_cb (TotemObject *totem, TotemChaptersPlugin *plugin); + static void add_chapter_to_the_list (gpointer data, gpointer user_data); + static void add_chapter_to_the_list_new (TotemChaptersPlugin *plugin, const gchar *title, gint64 time); +@@ -303,48 +303,47 @@ check_available_time (TotemChaptersPlugin *plugin, + } + + static void +-totem_file_opened_result_cb (gpointer data, +- gpointer user_data) ++totem_file_opened_result_cb (GObject *source_object, ++ GAsyncResult *res, ++ gpointer user_data) + { +- TotemCmmlAsyncData *adata; +- TotemChaptersPlugin *plugin; +- +- g_return_if_fail (data != NULL); +- +- adata = (TotemCmmlAsyncData *) data; +- plugin = TOTEM_CHAPTERS_PLUGIN (adata->user_data); ++ TotemChaptersPlugin *plugin = TOTEM_CHAPTERS_PLUGIN (user_data); ++ GError *error = NULL; ++ GList *list; ++ gboolean from_dialog; ++ gboolean is_exists; ++ ++ is_exists = TRUE; ++ list = totem_cmml_read_file_finish (G_FILE (source_object), res, &error); ++ ++ if (list == NULL) { ++ /* Ignore errors if file is not present */ ++ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) && ++ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) { ++ totem_action_error (plugin->priv->totem, _("Error while reading file with chapters"), ++ error->message); ++ g_error_free (error); + +- if (G_UNLIKELY (!adata->successful)) { +- if (G_UNLIKELY (g_cancellable_is_cancelled (adata->cancellable))) { +- /* if operation was cancelled due to plugin deactivation only clean up */ +- g_object_unref (adata->cancellable); +- g_free (adata->file); +- g_free (adata->error); +- g_list_foreach (adata->list, (GFunc) totem_cmml_clip_free, NULL); +- g_list_free (adata->list); +- g_free (adata); ++ set_no_data_visible (TRUE, TRUE, plugin); + return; +- } else +- totem_action_error (plugin->priv->totem, _("Error while reading file with chapters"), +- adata->error); ++ } ++ g_error_free (error); ++ is_exists = FALSE; + } + +- if (adata->is_exists && adata->from_dialog) { ++ from_dialog = GPOINTER_TO_INT(g_object_get_data (source_object, "from-dialog")); ++ ++ if (from_dialog) { + g_free (plugin->priv->cmml_mrl); +- plugin->priv->cmml_mrl = g_strdup (adata->file); ++ plugin->priv->cmml_mrl = g_file_get_uri (G_FILE (source_object)); + } + +- g_list_foreach (adata->list, (GFunc) add_chapter_to_the_list, plugin); +- g_list_foreach (adata->list, (GFunc) totem_cmml_clip_free, NULL); +- g_list_free (adata->list); ++ g_list_foreach (list, (GFunc) add_chapter_to_the_list, plugin); ++ g_list_foreach (list, (GFunc) totem_cmml_clip_free, NULL); ++ g_list_free (list); + + /* do not show tree if read operation failed */ +- set_no_data_visible (!adata->successful || !adata->is_exists, TRUE, plugin); +- +- g_object_unref (adata->cancellable); +- g_free (adata->file); +- g_free (adata->error); +- g_free (adata); ++ set_no_data_visible (!is_exists, TRUE, plugin); + } + + static void +@@ -607,7 +606,7 @@ load_chapters_from_file (const gchar *uri, + gboolean from_dialog, + TotemChaptersPlugin *plugin) + { +- TotemCmmlAsyncData *data; ++ GFile *file; + + g_return_if_fail (TOTEM_IS_CHAPTERS_PLUGIN (plugin)); + +@@ -616,27 +615,14 @@ load_chapters_from_file (const gchar *uri, + g_object_unref (plugin->priv->cancellable[0]); + } + +- data = g_new0 (TotemCmmlAsyncData, 1); +- /* do not forget to save this pointer in the result function */ +- data->file = g_strdup (uri); +- data->final = totem_file_opened_result_cb; +- data->user_data = (gpointer) plugin; +- if (from_dialog) +- data->from_dialog = TRUE; ++ file = g_file_new_for_uri (uri); ++ g_object_set_data (G_OBJECT (file), "from-dialog", GINT_TO_POINTER (from_dialog)); + /* cancellable object shouldn't be finalized during result func */ + plugin->priv->cancellable[0] = g_cancellable_new (); + g_object_add_weak_pointer (G_OBJECT (plugin->priv->cancellable[0]), + (gpointer *) &(plugin->priv->cancellable[0])); +- data->cancellable = plugin->priv->cancellable[0]; +- +- if (G_UNLIKELY (totem_cmml_read_file_async (data) < 0)) { +- g_warning ("chapters: wrong parameters for reading CMML file, may be a bug"); +- +- set_no_data_visible (TRUE, TRUE, plugin); + +- g_object_unref (plugin->priv->cancellable[0]); +- g_free (data); +- } ++ totem_cmml_read_file (file, plugin->priv->cancellable[0], totem_file_opened_result_cb, plugin); + } + + static void +diff --git a/src/plugins/chapters/totem-cmml-parser.c b/src/plugins/chapters/totem-cmml-parser.c +index e0ca7b2..39dc19d 100644 +--- a/src/plugins/chapters/totem-cmml-parser.c ++++ b/src/plugins/chapters/totem-cmml-parser.c +@@ -607,55 +607,45 @@ totem_cmml_clip_copy (TotemCmmlClip *clip) + } + + static void +-totem_cmml_read_file_result (GObject *source_object, +- GAsyncResult *result, +- gpointer user_data) ++totem_cmml_read_file_cb (GObject *source_object, ++ GAsyncResult *result, ++ gpointer user_data) + { + GError *error = NULL; + xmlTextReaderPtr reader; + TotemCmmlContext *context; +- TotemCmmlAsyncData *data; + gint ret; + gchar *contents; + gsize length; ++ gboolean load_ret; + ++ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); ++ GList *list = NULL; + +- data = (TotemCmmlAsyncData *) user_data; +- data->is_exists = TRUE; +- +- g_file_load_contents_finish (G_FILE (source_object), result, &contents, &length, NULL, &error); ++ load_ret = g_file_load_contents_finish (G_FILE (source_object), result, &contents, &length, NULL, &error); + g_object_unref (source_object); + +- if (G_UNLIKELY (error != NULL)) { +- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) || +- g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) { +- /* it's ok if file doesn't exist */ +- data->successful = TRUE; +- data->is_exists = FALSE; +- } else { +- data->successful = FALSE; +- data->error = g_strdup (error->message); +- g_warning ("chapters: failed to load CMML file %s: %s", data->file, error->message); +- } ++ if (!load_ret) { ++ g_simple_async_result_set_from_error (simple, error); ++ g_simple_async_result_complete_in_idle (simple); ++ g_object_unref (simple); + g_error_free (error); +- (data->final) (data, NULL); + return; + } + + /* parse in-memory xml data */ + reader = xmlReaderForMemory (contents, length, "", NULL, 0); + if (G_UNLIKELY (reader == NULL)) { +- g_warning ("chapters: failed to parse CMML file %s", data->file); +- g_free (contents); +- data->successful = FALSE; +- data->error = g_strdup (_("Failed to parse CMML file")); +- (data->final) (data, NULL); ++ g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_FAILED, ++ "Failed to parse CMML file"); ++ g_simple_async_result_complete_in_idle (simple); ++ g_object_unref (simple); + return; + } + + context = totem_cmml_context_new (); + context->reader = reader; +- totem_cmml_context_set_callback (context, totem_cmml_read_clip_cb, &(data->list)); ++ totem_cmml_context_set_callback (context, totem_cmml_read_clip_cb, &list); + + ret = xmlTextReaderRead (reader); + while (ret == 1) { +@@ -669,32 +659,61 @@ totem_cmml_read_file_result (GObject *source_object, + totem_cmml_context_free (context); + + /* sort clips by time growth */ +- data->list = g_list_sort (data->list, (GCompareFunc) totem_cmml_compare_clips); +- data->successful = TRUE; +- (data->final) (data, NULL); ++ list = g_list_sort (list, (GCompareFunc) totem_cmml_compare_clips); ++ ++ g_simple_async_result_set_op_res_gpointer (simple, list, NULL); ++ g_simple_async_result_complete_in_idle (simple); ++ g_object_unref (simple); + } + + /** +- * totem_cmml_read_file_async: +- * @data: #TotemCmmlAsyncData structure with info needed ++ * totem_cmml_read_file: ++ * @file: a #GFile representing the file to read ++ * @cancellable: optional #GCancellable object, %NULL to ignore ++ * @callback: a #GAsyncReadyCallback to call when the request is satisfied. ++ * @user_data: the data to pass to callback function. + * +- * Reads CMML file and parse it for clips in async way. ++ * Reads and parses a CMML file asynchronously. ++ **/ ++void ++totem_cmml_read_file (GFile *file, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GSimpleAsyncResult *simple; ++ ++ simple = g_simple_async_result_new (G_OBJECT (file), ++ callback, ++ user_data, ++ totem_cmml_read_file); ++ ++ g_file_load_contents_async (file, cancellable, totem_cmml_read_file_cb, simple); ++} ++ ++/** ++ * totem_ccml_read_file_finish: ++ * @file: a #GFile representing the file to read ++ * @res: a #GAsyncResult ++ * @error: a #GError, or %NULL + * +- * Returns: 0 if no errors occurred while starting async reading, -1 otherwise. ++ * Returns a list of parsed chapters or %NULL on error + **/ +-gint +-totem_cmml_read_file_async (TotemCmmlAsyncData *data) ++GList * ++totem_cmml_read_file_finish (GFile *file, ++ GAsyncResult *res, ++ GError **error) + { +- GFile *gio_file; ++ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); + +- g_return_val_if_fail (data != NULL, -1); +- g_return_val_if_fail (data->file != NULL, -1); +- g_return_val_if_fail (data->list == NULL, -1); +- g_return_val_if_fail (data->final != NULL, -1); ++ g_return_val_if_fail (G_IS_FILE (file), NULL); + +- gio_file = g_file_new_for_uri (data->file); +- g_file_load_contents_async (gio_file, data->cancellable, totem_cmml_read_file_result, data); +- return 0; ++ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == totem_cmml_read_file); ++ ++ if (g_simple_async_result_propagate_error (simple, error)) ++ return NULL; ++ ++ return g_simple_async_result_get_op_res_gpointer (simple); + } + + static void +diff --git a/src/plugins/chapters/totem-cmml-parser.h b/src/plugins/chapters/totem-cmml-parser.h +index 649a29c..f5db15f 100644 +--- a/src/plugins/chapters/totem-cmml-parser.h ++++ b/src/plugins/chapters/totem-cmml-parser.h +@@ -76,7 +76,14 @@ gchar * totem_cmml_convert_msecs_to_str (gint64 time_msecs); + TotemCmmlClip * totem_cmml_clip_new (const gchar *title, const gchar *desc, gint64 start, GdkPixbuf *pixbuf); + void totem_cmml_clip_free (TotemCmmlClip *clip); + TotemCmmlClip * totem_cmml_clip_copy (TotemCmmlClip *clip); +-gint totem_cmml_read_file_async (TotemCmmlAsyncData *data); ++ ++void totem_cmml_read_file (GFile *file, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data); ++GList *totem_cmml_read_file_finish (GFile *file, ++ GAsyncResult *res, ++ GError **error); + gint totem_cmml_write_file_async (TotemCmmlAsyncData *data); + + #endif /* TOTEM_CMML_PARSER_H_ */ +-- +cgit v0.9.1 diff -Nru totem-3.6.3/debian/patches/series totem-3.6.3/debian/patches/series --- totem-3.6.3/debian/patches/series 2013-02-27 10:11:35.000000000 -0500 +++ totem-3.6.3/debian/patches/series 2013-03-11 13:46:12.000000000 -0400 @@ -6,3 +6,4 @@ 92_gst-plugins-good.patch 93_grilo_optional.patch git_undefined_symbol.patch +git_refactor_async_chapters_loading.patch