bus: honour any per-thread default main context set via g_main_thread_push_thread_def...
authorTim-Philipp Müller <tim.muller@collabora.co.uk>
Mon, 31 Jan 2011 15:58:18 +0000 (15:58 +0000)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Mon, 31 Jan 2011 15:58:18 +0000 (15:58 +0000)
Makes gst_bus_add_watch(), gst_bus_add_watch_full(), gst_bus_add_signal_watch(),
and gst_bus_add_signal_watch_full() convenience functions automatically pick up
any non-default main contexts set for the current thread via
g_main_thread_push_thread_default().

gst/gstbus.c
tests/check/gst/gstbus.c

index f1096ea..bca4558 100644 (file)
@@ -831,6 +831,7 @@ static guint
 gst_bus_add_watch_full_unlocked (GstBus * bus, gint priority,
     GstBusFunc func, gpointer user_data, GDestroyNotify notify)
 {
+  GMainContext *ctx;
   guint id;
   GSource *source;
 
@@ -847,7 +848,8 @@ gst_bus_add_watch_full_unlocked (GstBus * bus, gint priority,
 
   g_source_set_callback (source, (GSourceFunc) func, user_data, notify);
 
-  id = g_source_attach (source, NULL);
+  ctx = g_main_context_get_thread_default ();
+  id = g_source_attach (source, ctx);
   g_source_unref (source);
 
   if (id) {
@@ -867,7 +869,11 @@ gst_bus_add_watch_full_unlocked (GstBus * bus, gint priority,
  * @notify: the function to call when the source is removed.
  *
  * Adds a bus watch to the default main context with the given @priority (e.g.
- * %G_PRIORITY_DEFAULT).
+ * %G_PRIORITY_DEFAULT). Since 0.10.33 it is also possible to use a non-default
+ * main context set up using g_main_context_push_thread_default() (before
+ * one had to create a bus watch source and attach it to the desired main
+ * context 'manually').
+ *
  * This function is used to receive asynchronous messages in the main loop.
  * There can only be a single bus watch per bus, you must remove it before you
  * can set a new one.
@@ -904,7 +910,11 @@ gst_bus_add_watch_full (GstBus * bus, gint priority,
  * @user_data: user data passed to @func.
  *
  * Adds a bus watch to the default main context with the default priority
- * (%G_PRIORITY_DEFAULT).
+ * (%G_PRIORITY_DEFAULT). Since 0.10.33 it is also possible to use a non-default
+ * main context set up using g_main_context_push_thread_default() (before
+ * one had to create a bus watch source and attach it to the desired main
+ * context 'manually').
+ *
  * This function is used to receive asynchronous messages in the main loop.
  * There can only be a single bus watch per bus, you must remove it before you
  * can set a new one.
@@ -1195,7 +1205,11 @@ gst_bus_disable_sync_message_emission (GstBus * bus)
  * @priority: The priority of the watch.
  *
  * Adds a bus signal watch to the default main context with the given @priority
- * (e.g. %G_PRIORITY_DEFAULT).
+ * (e.g. %G_PRIORITY_DEFAULT). Since 0.10.33 it is also possible to use a
+ * non-default main context set up using g_main_context_push_thread_default()
+ * (before one had to create a bus watch source and attach it to the desired
+ * main context 'manually').
+ *
  * After calling this statement, the bus will emit the "message" signal for each
  * message posted on the bus when the main loop is running.
  *
@@ -1250,7 +1264,11 @@ add_failed:
  * @bus: a #GstBus on which you want to receive the "message" signal
  *
  * Adds a bus signal watch to the default main context with the default priority
- * (%G_PRIORITY_DEFAULT).
+ * (%G_PRIORITY_DEFAULT). Since 0.10.33 it is also possible to use a non-default
+ * main context set up using g_main_context_push_thread_default() (before
+ * one had to create a bus watch source and attach it to the desired main
+ * context 'manually').
+ *
  * After calling this statement, the bus will emit the "message" signal for each
  * message posted on the bus.
  *
index 6519aed..f54d1a5 100644 (file)
@@ -241,6 +241,48 @@ GST_START_TEST (test_watch_with_custom_context)
 
 GST_END_TEST;
 
+/* test if adding a signal watch for different message types calls the
+ * respective callbacks. */
+GST_START_TEST (test_add_watch_with_custom_context)
+{
+  GMainContext *ctx;
+  GSource *source;
+  guint num_eos = 0;
+  guint num_app = 0;
+
+  test_bus = gst_bus_new ();
+
+  ctx = g_main_context_new ();
+  main_loop = g_main_loop_new (ctx, FALSE);
+
+  g_main_context_push_thread_default (ctx);
+  gst_bus_add_signal_watch (test_bus);
+  g_main_context_pop_thread_default (ctx);
+
+  g_signal_connect (test_bus, "message::eos", (GCallback) message_func_eos,
+      &num_eos);
+  g_signal_connect (test_bus, "message::application",
+      (GCallback) message_func_app, &num_app);
+
+  source = g_idle_source_new ();
+  g_source_set_callback (source, (GSourceFunc) send_messages, NULL, NULL);
+  g_source_attach (source, ctx);
+  g_source_unref (source);
+
+  while (g_main_context_pending (ctx))
+    g_main_context_iteration (ctx, FALSE);
+
+  fail_unless_equals_int (num_eos, 10);
+  fail_unless_equals_int (num_app, 10);
+
+  g_main_loop_unref (main_loop);
+  g_main_context_unref (ctx);
+
+  gst_object_unref (test_bus);
+}
+
+GST_END_TEST;
+
 static gint messages_seen;
 
 static void
@@ -581,6 +623,7 @@ gst_bus_suite (void)
   tcase_add_test (tc_chain, test_watch);
   tcase_add_test (tc_chain, test_watch_with_poll);
   tcase_add_test (tc_chain, test_watch_with_custom_context);
+  tcase_add_test (tc_chain, test_add_watch_with_custom_context);
   tcase_add_test (tc_chain, test_timed_pop);
   tcase_add_test (tc_chain, test_timed_pop_thread);
   tcase_add_test (tc_chain, test_timed_pop_filtered);