Add private glib_get_worker_context() API
authorRyan Lortie <desrt@desrt.ca>
Wed, 31 Aug 2011 22:20:24 +0000 (18:20 -0400)
committerRyan Lortie <desrt@desrt.ca>
Fri, 9 Sep 2011 17:40:50 +0000 (13:40 -0400)
The first time this is called, this creates a GMainContext * and a
thread to run it.  Future calls return the same.  There are a lot of
places that we could use this in GLib.

glib/Makefile.am
glib/glib.symbols
glib/glibprivate.h [new file with mode: 0644]
glib/gmain.c

index d92f0e6..863b2b0 100644 (file)
@@ -113,6 +113,7 @@ uninstall-ms-lib:
 
 libglib_2_0_la_SOURCES =       \
        glib_probes.d           \
+       glibprivate.h           \
        garray.c                \
        gasyncqueue.c           \
        gatomic.c               \
index 524f245..cf0aeb7 100644 (file)
@@ -1273,6 +1273,7 @@ g_utf16_to_ucs4
 g_utf16_to_utf8
 g_unichar_to_utf8
 g_unichar_validate
+glib_get_worker_context
 glib_pgettext
 glib_gettext
 #ifdef G_OS_WIN32
diff --git a/glib/glibprivate.h b/glib/glibprivate.h
new file mode 100644 (file)
index 0000000..2f95369
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __GLIBPRIVATE_H__
+#define __GLIBPRIVATE_H__
+
+GMainContext *glib_get_worker_context (void);
+
+#endif /* __GLIBPRIVATE_H__ */
index 9c65c5a..7783954 100644 (file)
@@ -98,6 +98,8 @@
 
 #include "gwakeup.h"
 
+#include "glibprivate.h"
+
 /**
  * SECTION:main
  * @title: The Main Event Loop
@@ -378,6 +380,8 @@ static gboolean g_idle_dispatch    (GSource     *source,
                                    GSourceFunc  callback,
                                    gpointer     user_data);
 
+static GMainContext *glib_worker_context;
+
 G_LOCK_DEFINE_STATIC (main_loop);
 static GMainContext *default_main_context;
 static GSList *main_contexts_without_pipe = NULL;
@@ -4954,3 +4958,35 @@ g_main_context_invoke_full (GMainContext   *context,
         }
     }
 }
+
+static gpointer
+glib_worker_main (gpointer data)
+{
+  LOCK_CONTEXT (glib_worker_context);
+
+  while (TRUE)
+    g_main_context_iterate (glib_worker_context, TRUE, TRUE, G_THREAD_SELF);
+
+  return NULL; /* worst GCC warning message ever... */
+}
+
+GMainContext *
+glib_get_worker_context (void)
+{
+  gsize initialised;
+
+  g_thread_init_glib ();
+
+  if (g_once_init_enter (&initialised))
+    {
+      GError *error = NULL;
+
+      glib_worker_context = g_main_context_new ();
+      if (g_thread_create (glib_worker_main, NULL, FALSE, &error) == NULL)
+        g_error ("Creating GLib worker thread failed: %s\n", error->message);
+
+      g_once_init_leave (&initialised, TRUE);
+    }
+
+  return glib_worker_context;
+}