[glibmm] Signal*::connect(): Make them less thread-unsafe.



commit 3aa8e5d2929dceec4f1c0ded5fcbf208c93e1dc9
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Thu Feb 21 08:57:49 2013 +0100

    Signal*::connect(): Make them less thread-unsafe.
    
    * glib/glibmm/main.cc: Make SignalTimeout::connect(), connect_seconds(),
    SignalIdle::connect() and SignalChildWatch::connect() less thread-unsafe
    by moving conn_node->install() to before g_source_attach().
    * glib/glibmm/main.h: Describe that the Signal*::connect*() methods that
    return a sigc::connection are not thread-safe. Bug #396958.

 ChangeLog           |   10 ++++++++++
 glib/glibmm/main.cc |   10 +++++-----
 glib/glibmm/main.h  |   30 ++++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 5 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index cdcf207..7c13c23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2013-02-21  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+
+       Signal*::connect(): Make them less thread-unsafe.
+
+       * glib/glibmm/main.cc: Make SignalTimeout::connect(), connect_seconds(),
+       SignalIdle::connect() and SignalChildWatch::connect() less thread-unsafe
+       by moving conn_node->install() to before g_source_attach().
+       * glib/glibmm/main.h: Describe that the Signal*::connect*() methods that
+       return a sigc::connection are not thread-safe. Bug #396958.
+
 2013-02-20  Kjell Ahlstedt  <kjell ahlstedt bredband net>
 
        Signal[Timeout|Idle]::connect_once() docs: Warn about thread-unsafety.
diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc
index 99ae7a7..e48756d 100644
--- a/glib/glibmm/main.cc
+++ b/glib/glibmm/main.cc
@@ -285,7 +285,7 @@ static void glibmm_signal_connect_once(const sigc::slot<void>& slot, int priorit
 
   conn_node->install(source);
   g_source_attach(source, context);
-  g_source_unref(source);
+  g_source_unref(source); // GMainContext holds a reference
 }
 
 } // anonymous namespace
@@ -342,10 +342,10 @@ sigc::connection SignalTimeout::connect(const sigc::slot<bool>& slot,
       source, &glibmm_source_callback, conn_node,
       &SourceConnectionNode::destroy_notify_callback);
 
+  conn_node->install(source);
   g_source_attach(source, context_);
   g_source_unref(source); // GMainContext holds a reference
 
-  conn_node->install(source);
   return connection;
 }
 
@@ -372,10 +372,10 @@ sigc::connection SignalTimeout::connect_seconds(const sigc::slot<bool>& slot,
       source, &glibmm_source_callback, conn_node,
       &SourceConnectionNode::destroy_notify_callback);
 
+  conn_node->install(source);
   g_source_attach(source, context_);
   g_source_unref(source); // GMainContext holds a reference
 
-  conn_node->install(source);
   return connection;
 }
 
@@ -414,10 +414,10 @@ sigc::connection SignalIdle::connect(const sigc::slot<bool>& slot, int priority)
       source, &glibmm_source_callback, conn_node,
       &SourceConnectionNode::destroy_notify_callback);
 
+  conn_node->install(source);
   g_source_attach(source, context_);
   g_source_unref(source); // GMainContext holds a reference
 
-  conn_node->install(source);
   return connection;
 }
 
@@ -500,10 +500,10 @@ sigc::connection SignalChildWatch::connect(const sigc::slot<void, GPid, int>& sl
       source, (GSourceFunc)&glibmm_child_watch_callback, conn_node,
       &SourceConnectionNode::destroy_notify_callback);
 
+  conn_node->install(source);
   g_source_attach(source, context_);
   g_source_unref(source); // GMainContext holds a reference
 
-  conn_node->install(source);
   return connection;
 }
 
diff --git a/glib/glibmm/main.h b/glib/glibmm/main.h
index 345259e..bc0dd21 100644
--- a/glib/glibmm/main.h
+++ b/glib/glibmm/main.h
@@ -111,6 +111,11 @@ public:
    * timeout_source->connect(sigc::ptr_fun(&timeout_handler));
    * timeout_source->attach(Glib::MainContext::get_default());
    * @endcode
+   *
+   * This method is not thread-safe. You should call it, or manipulate the
+   * returned sigc::connection object, only from the thread where the SignalTimeout
+   * object's MainContext runs.
+   *
    * @param slot A slot to call when @a interval has elapsed.
    * If <tt>timeout_handler()</tt> returns <tt>false</tt> the handler is disconnected.
    * @param interval The timeout in milliseconds.
@@ -164,6 +169,11 @@ public:
    * timeout_source->connect(sigc::ptr_fun(&timeout_handler));
    * timeout_source->attach(Glib::MainContext::get_default());
    * @endcode
+   *
+   * This method is not thread-safe. You should call it, or manipulate the
+   * returned sigc::connection object, only from the thread where the SignalTimeout
+   * object's MainContext runs.
+   *
    * @param slot A slot to call when @a interval has elapsed.
    * If <tt>timeout_handler()</tt> returns <tt>false</tt> the handler is disconnected.
    * @param interval The timeout in seconds.
@@ -226,6 +236,11 @@ public:
    * idle_source->connect(sigc::ptr_fun(&idle_handler));
    * idle_source->attach(Glib::MainContext::get_default());
    * @endcode
+   *
+   * This method is not thread-safe. You should call it, or manipulate the
+   * returned sigc::connection object, only from the thread where the SignalIdle
+   * object's MainContext runs.
+   *
    * @param slot A slot to call when the main loop is idle.
    * If <tt>idle_handler()</tt> returns <tt>false</tt> the handler is disconnected.
    * @param priority The priority of the new event source.
@@ -280,6 +295,11 @@ public:
    * io_source->connect(sigc::ptr_fun(&io_handler));
    * io_source->attach(Glib::MainContext::get_default());
    * @endcode
+   *
+   * This method is not thread-safe. You should call it, or manipulate the
+   * returned sigc::connection object, only from the thread where the SignalIO
+   * object's MainContext runs.
+   *
    * @param slot A slot to call when polling @a fd results in an event that matches @a condition.
    * The event will be passed as a parameter to @a slot.
    * If <tt>io_handler()</tt> returns <tt>false</tt> the handler is disconnected.
@@ -303,6 +323,11 @@ public:
    * io_source->connect(sigc::ptr_fun(&io_handler));
    * io_source->attach(Glib::MainContext::get_default());
    * @endcode
+   *
+   * This method is not thread-safe. You should call it, or manipulate the
+   * returned sigc::connection object, only from the thread where the SignalIO
+   * object's MainContext runs.
+   *
    * @param slot A slot to call when polling @a channel results in an event that matches @a condition.
    * The event will be passed as a parameter to @a slot.
    * If <tt>io_handler()</tt> returns <tt>false</tt> the handler is disconnected.
@@ -332,6 +357,11 @@ public:
    * void child_watch_handler(GPid pid, int child_status) { ... }
    * Glib::signal_child_watch().connect(sigc::ptr_fun(&child_watch_handler), pid);
    * @endcode
+   *
+   * This method is not thread-safe. You should call it, or manipulate the
+   * returned sigc::connection object, only from the thread where the SignalChildWatch
+   * object's MainContext runs.
+   *
    * @param slot A slot to call when child process @a pid exited.
    * @param pid The child process to watch for.
    * @param priority The priority of the new event source.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]