gst/gst.c: Call g_thread_init() first thing in gst_init() / gst_check_init().
authorTim-Philipp Müller <tim@centricular.net>
Fri, 5 Jan 2007 16:36:36 +0000 (16:36 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Fri, 5 Jan 2007 16:36:36 +0000 (16:36 +0000)
Original commit message from CVS:
* gst/gst.c: (gst_init_get_option_group), (gst_init_check),
(init_pre):
Call g_thread_init() first thing in gst_init() / gst_check_init().
When initialisation is done via gst_init_get_option_group() and
GOption parsing, issue a warning if the GLib thread system has not
been initialised yet by the time gst_init_get_option_group() is
called, as it's quite likely other GLib functions such as
g_option_context_new() have been called already then, and
g_thread_init() must be called before any other GLib function. The
application in question must be fixed in that case, since memory
corruption might happen otherwise.
We issue the warning because even if the GLib folks decide to work
around the problem on their end in future, this is still an issue
with all GLib versions >= 2.10.0, so we should warn until we depend
on a GLib version we know to be safe.
Update documentation as well.
Closes bug #391278.

ChangeLog
gst/gst.c

index 63061c0..5a97bd3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 2007-01-05  Tim-Philipp Müller  <tim at centricular dot net>
 
+       * gst/gst.c: (gst_init_get_option_group), (gst_init_check),
+       (init_pre):
+         Call g_thread_init() first thing in gst_init() / gst_check_init().
+         When initialisation is done via gst_init_get_option_group() and
+         GOption parsing, issue a warning if the GLib thread system has not
+         been initialised yet by the time gst_init_get_option_group() is
+         called, as it's quite likely other GLib functions such as
+         g_option_context_new() have been called already then, and
+         g_thread_init() must be called before any other GLib function. The
+         application in question must be fixed in that case, since memory
+         corruption might happen otherwise.
+         We issue the warning because even if the GLib folks decide to work
+         around the problem on their end in future, this is still an issue
+         with all GLib versions >= 2.10.0, so we should warn until we depend
+         on a GLib version we know to be safe.
+         Update documentation as well.
+         Closes bug #391278.
+
+2007-01-05  Tim-Philipp Müller  <tim at centricular dot net>
+
        * tools/gst-inspect.c: (main):
        * tools/gst-launch.c: (main):
        * tools/gst-typefind.c: (main):
index 6ad290a..77c42f5 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
  *       N_("Output tags (also known as metadata)"), NULL},
  *   {NULL}
  *  };
- *  ctx = g_option_context_new ("gst-launch");
+ *  // must initialise the threading system before using any other GLib funtion
+ *  if (!g_thread_supported ())
+ *    g_thread_init (NULL);
+ *  ctx = g_option_context_new ("[ADDITIONAL ARGUMENTS]");
  *  g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
  *  g_option_context_add_group (ctx, gst_init_get_option_group ());
  *  if (!g_option_context_parse (ctx, &amp;argc, &amp;argv, &amp;err)) {
@@ -279,8 +282,11 @@ parse_debug_list (const gchar * list)
  * This function is useful if you want to integrate GStreamer with other
  * libraries that use GOption (see g_option_context_add_group() ).
  *
- * Returns: a pointer to GStreamer's option group. Should be dereferenced
- * after use.
+ * If you use this function, you should make sure you initialise the GLib
+ * threading system as one of the very first things in your program
+ * (see the example at the beginning of this section).
+ *
+ * Returns: a pointer to GStreamer's option group.
  */
 
 GOptionGroup *
@@ -337,6 +343,20 @@ gst_init_get_option_group (void)
     {NULL}
   };
 
+  /* The GLib threading system must be initialised before calling any other
+   * GLib function according to the documentation; if the application hasn't
+   * called gst_init() yet or initialised the threading system otherwise, we
+   * better issue a warning here (since chances are high that the application
+   * has already called other GLib functions such as g_option_context_new() */
+  if (!g_thread_supported ()) {
+    g_warning ("The GStreamer function gst_init_get_option_group() was\n"
+        "\tcalled, but the GLib threading system has not been initialised\n"
+        "\tyet, something that must happen before any other GLib function\n"
+        "\tis called. The application needs to be fixed accordingly, please\n"
+        "\tfile a bug against this application.");
+    g_thread_init (NULL);
+  }
+
   group = g_option_group_new ("gst", _("GStreamer Options"),
       _("Show GStreamer Options"), NULL, NULL);
   g_option_group_set_parse_hooks (group, (GOptionParseFunc) init_pre,
@@ -361,6 +381,10 @@ gst_init_get_option_group (void)
  * for some reason.  If you want your program to fail fatally,
  * use gst_init() instead.
  *
+ * This function should be called before calling any other GLib functions. If
+ * this is not an option, your program must initialise the GLib thread system
+ * using g_thread_init() before any other GLib functions are called.
+ *
  * Returns: %TRUE if GStreamer could be initialized.
  */
 gboolean
@@ -370,6 +394,9 @@ gst_init_check (int *argc, char **argv[], GError ** err)
   GOptionContext *ctx;
   gboolean res;
 
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
+
   GST_INFO ("initializing GStreamer");
 
   if (gst_initialized) {
@@ -403,6 +430,10 @@ gst_init_check (int *argc, char **argv[], GError ** err)
  * Initializes the GStreamer library, setting up internal path lists,
  * registering built-in elements, and loading standard plugins.
  *
+ * This function should be called before calling any other GLib functions. If
+ * this is not an option, your program must initialise the GLib thread system
+ * using g_thread_init() before any other GLib functions are called.
+ *
  * <note><para>
  * This function will terminate your program if it was unable to initialize
  * GStreamer for some reason.  If you want your program to fall back,
@@ -519,12 +550,8 @@ init_pre (GOptionContext * context, GOptionGroup * group, gpointer data,
 
   g_type_init ();
 
-  if (g_thread_supported ()) {
-    /* somebody already initialized threading */
-  } else {
-    g_thread_init (NULL);
-  }
   /* we need threading to be enabled right here */
+  g_assert (g_thread_supported ());
   _gst_debug_init ();
 
 #ifdef ENABLE_NLS