[glibmm] Glib::MainContext: Add push/pop/get_thread_default()
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] Glib::MainContext: Add push/pop/get_thread_default()
- Date: Mon, 7 Oct 2019 16:29:42 +0000 (UTC)
commit 3ee32657ac9386463b2c539aaf7500343ba25af0
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Mon Oct 7 18:27:21 2019 +0200
Glib::MainContext: Add push/pop/get_thread_default()
See issue #56
glib/glibmm/main.cc | 20 ++++++++++++++
glib/glibmm/main.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 92 insertions(+), 4 deletions(-)
---
diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc
index 3ca2c739..038b4711 100644
--- a/glib/glibmm/main.cc
+++ b/glib/glibmm/main.cc
@@ -652,6 +652,26 @@ MainContext::remove_poll(PollFD& fd)
g_main_context_remove_poll(gobj(), fd.gobj());
}
+void
+MainContext::push_thread_default()
+{
+ g_main_context_push_thread_default(gobj());
+}
+
+void
+MainContext::pop_thread_default()
+{
+ g_main_context_pop_thread_default(gobj());
+}
+
+// static
+Glib::RefPtr<MainContext>
+MainContext::get_thread_default()
+{
+ // g_main_context_ref_thread_default() gives us a ref.
+ return Glib::wrap(g_main_context_ref_thread_default(), false);
+}
+
void
MainContext::invoke(const sigc::slot<bool()>& slot, int priority)
{
diff --git a/glib/glibmm/main.h b/glib/glibmm/main.h
index c2f799c8..aa03d96e 100644
--- a/glib/glibmm/main.h
+++ b/glib/glibmm/main.h
@@ -390,10 +390,12 @@ public:
* @return The new MainContext.
*/
static Glib::RefPtr<MainContext> create();
- /** Returns the default main context.
- * This is the main context used for main loop functions when a main loop is not explicitly
- * specified.
- * @return The new MainContext.
+ /** Returns the global default main context.
+ * This is the main context used for main loop functions when a main loop
+ * is not explicitly specified, and corresponds to the "main" main loop.
+ *
+ * @return The global default main context.
+ * @see get_thread_default()
*/
static Glib::RefPtr<MainContext> get_default();
@@ -502,6 +504,72 @@ public:
*/
void remove_poll(PollFD& fd);
+ /** Acquires the context and sets it as the thread-default context for the current thread.
+ *
+ * This will cause certain asynchronous operations (such as most gio-based I/O)
+ * which are started in this thread to run under this context and deliver their
+ * results to its main loop, rather than running under the global
+ * default context in the main thread. Note that calling this function
+ * changes the context returned by get_thread_default(),
+ * not the one returned by get_default(), so it does not affect
+ * the context used by functions like g_idle_add().
+ *
+ * Normally you would call this function shortly after creating a new
+ * thread, passing it a Glib::MainContext which will be run by a
+ * Glib::MainLoop in that thread, to set a new default context for all
+ * async operations in that thread. In this case you may not need to
+ * ever call pop_thread_default(), assuming you want the
+ * new Glib::MainContext to be the default for the whole lifecycle of the
+ * thread.
+ *
+ * If you don't have control over how the new thread was created (e.g.
+ * if the new thread isn't newly created, or if the thread life
+ * cycle is managed by a GThreadPool), it is always suggested to wrap
+ * the logic that needs to use the new Glib::MainContext inside a
+ * push_thread_default() / pop_thread_default()
+ * pair, otherwise threads that are re-used will end up never explicitly
+ * releasing the Glib::MainContext reference they hold.
+ *
+ * In some cases you may want to schedule a single operation in a
+ * non-default context, or temporarily use a non-default context in
+ * the main thread. In that case, you can wrap the call to the
+ * asynchronous operation inside a push_thread_default() / pop_thread_default()
+ * pair, but it is up to you to ensure that no other asynchronous operations
+ * accidentally get started while the non-default context is active.
+ *
+ * Beware that libraries that predate this function may not correctly
+ * handle being used from a thread with a thread-default context. Eg,
+ * see Gio::File::supports_thread_contexts().
+ *
+ * @newin{2,64}
+ */
+ void push_thread_default();
+
+ /** Pops the context off the thread-default context stack (verifying that
+ * it was on the top of the stack).
+ *
+ * @newin{2,64}
+ */
+ void pop_thread_default();
+
+ /** Gets the thread-default MainContext for this thread.
+ * Asynchronous operations that want to be able to be run in contexts
+ * other than the default one should call this method to get a MainContext
+ * to add their Glib::Sources to. (Note that even in single-threaded
+ * programs applications may sometimes want to temporarily push a
+ * non-default context, so it is not safe to assume that this will
+ * always return the global default context if you are running in
+ * the default thread.)
+ *
+ * This method wraps g_main_context_ref_thread_default(),
+ * and not g_main_context_get_thread_default().
+ *
+ * @return The thread-default MainContext.
+ *
+ * @newin{2,64}
+ */
+ static Glib::RefPtr<MainContext> get_thread_default();
+
/** Invokes a function in such a way that this MainContext is owned during
* the invocation of @a slot.
*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]