[totem-pl-parser] Bug 590389 – plparse/tests/parser is broken



commit 98ef363bfe224e5d68b2d5068c9a3f16df3369b1
Author: Philip Withnall <philip tecnocode co uk>
Date:   Fri Jul 31 20:01:14 2009 +0100

    Bug 590389 â?? plparse/tests/parser is broken
    
    Change how signals are emitted from the playlist parsing process so they're
    once more emitted synchronously when we're parsing synchronously, and in
    idle callbacks when we're parsing asynchronously. This solves the awkward
    problem of all the TotemPlParser::entry-parsed signals being emitted after
    a call to a synchronous parse function had returned. Closes: bgo#590389

 plparse/totem-pl-parser-private.h |   26 ++++++++++++++++++++++++++
 plparse/totem-pl-parser.c         |    6 ++++--
 2 files changed, 30 insertions(+), 2 deletions(-)
---
diff --git a/plparse/totem-pl-parser-private.h b/plparse/totem-pl-parser-private.h
index 9070bc4..deae8d7 100644
--- a/plparse/totem-pl-parser-private.h
+++ b/plparse/totem-pl-parser-private.h
@@ -26,6 +26,32 @@
 #include <glib.h>
 #include "totem_internal.h"
 
+/* A macro to call functions synchronously or asynchronously, depending on whether
+ * we're parsing sync or async. This is necessary because when doing a sync parse,
+ * the main loop isn't iterated, and so any signals emitted in idle functions (a requirement
+ * of an async parse) aren't emitted until the sync parsing function returns, which
+ * is less than ideal. We therefore want those idle functions to be called synchronously
+ * when parsing sync, and with g_idle_add() when parsing async.
+ *
+ * Whether we're parsing sync or async is determined by whether we're in a thread. If (for
+ * whatever reason), we're parsing async -- but not in a thread -- this will work out fine
+ * anyway, since signal emission will consequently happen in the main thread.
+ *
+ * We determine if we're in the main thread by comparing the GThread pointer of the current
+ * thread to a stored GThread pointer known to be from the main thread
+ * (TotemPlParser->priv->main_thread).
+ *
+ * @p: a #TotemPlParser
+ * @c: callback (as if for g_idle_add())
+ * @d: callback data
+ */
+#define CALL_ASYNC(p, c, d) {				\
+	if (g_thread_self () == p->priv->main_thread)	\
+		c (d);					\
+	else						\
+		g_idle_add ((GSourceFunc) c, d);	\
+}
+
 #ifndef TOTEM_PL_PARSER_MINI
 #include "totem-pl-parser.h"
 #include <glib-object.h>
diff --git a/plparse/totem-pl-parser.c b/plparse/totem-pl-parser.c
index 42c6bad..6563a41 100644
--- a/plparse/totem-pl-parser.c
+++ b/plparse/totem-pl-parser.c
@@ -255,6 +255,7 @@ struct TotemPlParserPrivate {
 	GList *ignore_schemes;
 	GList *ignore_mimetypes;
 	GMutex *ignore_mutex;
+	GThread *main_thread; /* see CALL_ASYNC() in *-private.h */
 
 	guint recurse : 1;
 	guint debug : 1;
@@ -703,7 +704,7 @@ totem_pl_parser_playlist_end (TotemPlParser *parser, const char *playlist_uri)
 	data->parser = g_object_ref (parser);
 	data->playlist_uri = g_strdup (playlist_uri);
 
-	g_idle_add ((GSourceFunc) emit_playlist_ended_signal, data);
+	CALL_ASYNC (parser, emit_playlist_ended_signal, data);
 }
 
 static char *
@@ -1289,6 +1290,7 @@ totem_pl_parser_init (TotemPlParser *parser)
 {
 	parser->priv = G_TYPE_INSTANCE_GET_PRIVATE (parser, TOTEM_TYPE_PL_PARSER, TotemPlParserPrivate);
 	parser->priv->ignore_mutex = g_mutex_new ();
+	parser->priv->main_thread = g_thread_self ();
 }
 
 static void
@@ -1457,7 +1459,7 @@ totem_pl_parser_add_uri_valist (TotemPlParser *parser,
 		else
 			data->signal_id = totem_pl_parser_table_signals[PLAYLIST_STARTED];
 
-		g_idle_add ((GSourceFunc) emit_entry_parsed_signal, data);
+		CALL_ASYNC (parser, emit_entry_parsed_signal, data);
 	}
 
 	g_hash_table_unref (metadata);



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