From 1facd36d00fc5fc18fa9d690979f9e73c0f1d312 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Wed, 31 Aug 2011 18:20:24 -0400 Subject: [PATCH] Add private glib_get_worker_context() API 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 | 1 + glib/glib.symbols | 1 + glib/glibprivate.h | 6 ++++++ glib/gmain.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 glib/glibprivate.h diff --git a/glib/Makefile.am b/glib/Makefile.am index d92f0e695..863b2b0ec 100644 --- a/glib/Makefile.am +++ b/glib/Makefile.am @@ -113,6 +113,7 @@ uninstall-ms-lib: libglib_2_0_la_SOURCES = \ glib_probes.d \ + glibprivate.h \ garray.c \ gasyncqueue.c \ gatomic.c \ diff --git a/glib/glib.symbols b/glib/glib.symbols index 524f2456d..cf0aeb7f4 100644 --- a/glib/glib.symbols +++ b/glib/glib.symbols @@ -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 index 000000000..2f95369eb --- /dev/null +++ b/glib/glibprivate.h @@ -0,0 +1,6 @@ +#ifndef __GLIBPRIVATE_H__ +#define __GLIBPRIVATE_H__ + +GMainContext *glib_get_worker_context (void); + +#endif /* __GLIBPRIVATE_H__ */ diff --git a/glib/gmain.c b/glib/gmain.c index 9c65c5aa5..778395412 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -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; +}