[glibmm] Glib::MainContext: Add invoke().
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] Glib::MainContext: Add invoke().
- Date: Sun, 2 Jun 2013 13:44:28 +0000 (UTC)
commit 47f1dedf040506b4aa7d131311866d8121bdbd8b
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Sun Jun 2 15:06:55 2013 +0200
Glib::MainContext: Add invoke().
* glib/glibmm/main.[h|cc]: Add Glib::MainContext::invoke(). Bug #668184.
ChangeLog | 6 ++++++
glib/glibmm/main.cc | 31 +++++++++++++++++++++++++++++++
glib/glibmm/main.h | 32 ++++++++++++++++++++++++++++++++
3 files changed, 69 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 7af8493..e67293e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-06-02 Kjell Ahlstedt <kjell ahlstedt bredband net>
+
+ Glib::MainContext: Add invoke().
+
+ * glib/glibmm/main.[h|cc]: Add Glib::MainContext::invoke(). Bug #668184.
+
2013-05-21 Kjell Ahlstedt <kjell ahlstedt bredband net>
Add missing includes in glibmm.h and bytearray.hg.
diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc
index 173f831..f6707b7 100644
--- a/glib/glibmm/main.cc
+++ b/glib/glibmm/main.cc
@@ -319,6 +319,28 @@ static void glibmm_signal_connect_once(const sigc::slot<void>& slot, int priorit
g_source_unref(source); // GMainContext holds a reference
}
+gboolean glibmm_main_context_invoke_callback(void* data)
+{
+ sigc::slot_base *const slot = reinterpret_cast<sigc::slot_base*>(data);
+
+ try
+ {
+ // Recreate the specific slot from the generic slot node.
+ return (*static_cast<sigc::slot<bool>*>(slot))();
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ return 0;
+}
+
+void glibmm_main_context_invoke_destroy_notify_callback(void* data)
+{
+ sigc::slot_base *const slot = reinterpret_cast<sigc::slot_base*>(data);
+ delete slot;
+}
+
} // anonymous namespace
@@ -655,6 +677,15 @@ void MainContext::remove_poll(PollFD& fd)
g_main_context_remove_poll(gobj(), fd.gobj());
}
+void MainContext::invoke(const sigc::slot<bool>& slot, int priority)
+{
+ // Make a copy of slot on the heap.
+ sigc::slot_base* const slot_copy = new sigc::slot<bool>(slot);
+
+ g_main_context_invoke_full(gobj(), priority, glibmm_main_context_invoke_callback,
+ slot_copy, glibmm_main_context_invoke_destroy_notify_callback);
+}
+
SignalTimeout MainContext::signal_timeout()
{
return SignalTimeout(gobj());
diff --git a/glib/glibmm/main.h b/glib/glibmm/main.h
index bc0dd21..cd07857 100644
--- a/glib/glibmm/main.h
+++ b/glib/glibmm/main.h
@@ -524,6 +524,38 @@ public:
*/
void remove_poll(PollFD& fd);
+ /** Invokes a function in such a way that this MainContext is owned during
+ * the invocation of @a slot.
+ *
+ * If the context is owned by the current thread, @a slot is called
+ * directly. Otherwise, if the context is the thread-default main context
+ * of the current thread and acquire() succeeds, then
+ * @a slot is called and release() is called afterwards.
+ *
+ * In any other case, an idle source is created to call @a slot and
+ * that source is attached to the context (presumably to be run in another
+ * thread).
+ *
+ * Note that, as with normal idle functions, @a slot should probably
+ * return <tt>false</tt>. If it returns <tt>true</tt>, it will be continuously
+ * run in a loop (and may prevent this call from returning).
+ *
+ * If an idle source is created to call @a slot, invoke() may return before
+ * @a slot is called.
+ *
+ * Because sigc::trackable is not thread-safe, if the slot represents a
+ * non-static method of a class deriving from sigc::trackable, and the slot is
+ * created by sigc::mem_fun(), invoke() should only be called from
+ * the thread where the context runs. You can use, say, boost::bind() or,
+ * in C++11, std::bind() or a C++11 lambda expression instead of sigc::mem_fun().
+ *
+ * @param slot A slot to call.
+ * @param priority The priority of the idle source, if one is created.
+ *
+ * @newin{2,38}
+ */
+ void invoke(const sigc::slot<bool>& slot, int priority = PRIORITY_DEFAULT);
+
/** Timeout signal, attached to this MainContext.
* @return A signal proxy; you want to use SignalTimeout::connect().
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]