[glibmm] Signal[Timeout|Idle]::connect_once() docs: Warn about thread-unsafety.
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] Signal[Timeout|Idle]::connect_once() docs: Warn about thread-unsafety.
- Date: Wed, 20 Feb 2013 17:54:20 +0000 (UTC)
commit 6cba8b3271b5c5def5a386b076420615c78fe4b7
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Wed Feb 20 17:24:28 2013 +0100
Signal[Timeout|Idle]::connect_once() docs: Warn about thread-unsafety.
* glib/glibmm/main.cc: Fix an incomplete comment.
* glib/glibmm/main.h: SignalTimeout::connect_once(), connect_seconds_once(),
SignalIdle::connect_once(): Describe the caution necessary because
sigc::trackable-derived objects are not thread-safe. Bug #396963.
ChangeLog | 9 ++++
glib/glibmm/main.cc | 6 +-
glib/glibmm/main.h | 104 +++++++++++++++++++++++++++++++++------------------
3 files changed, 79 insertions(+), 40 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 1a85f96..cdcf207 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2013-02-20 Kjell Ahlstedt <kjell ahlstedt bredband net>
+ Signal[Timeout|Idle]::connect_once() docs: Warn about thread-unsafety.
+
+ * glib/glibmm/main.cc: Fix an incomplete comment.
+ * glib/glibmm/main.h: SignalTimeout::connect_once(), connect_seconds_once(),
+ SignalIdle::connect_once(): Describe the caution necessary because
+ sigc::trackable-derived objects are not thread-safe. Bug #396963.
+
+2013-02-20 Kjell Ahlstedt <kjell ahlstedt bredband net>
+
ThreadPool::push() docs: Note that sigc::trackable is not thread-safe.
* glib/glibmm/threadpool.h: push(): Describe how sigc::trackable-derived
diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc
index 47f2638..99ae7a7 100644
--- a/glib/glibmm/main.cc
+++ b/glib/glibmm/main.cc
@@ -214,9 +214,9 @@ static gboolean glibmm_source_callback(void* data)
return 0;
}
-/* Only used by SignalTimeout::connect_once() and SignalIdle::connect_once().
- * These don't use Glib::Source, to avoid the unnecessary overhead
- * of a completely unused wrapper object.
+/* Only used by SignalTimeout::connect_once(), SignalTimeout::connect_seconds_once()
+ * and SignalIdle::connect_once(). These don't use Glib::Source, to avoid the
+ * unnecessary overhead of a completely unused wrapper object.
*/
static gboolean glibmm_source_callback_once(void* data)
{
diff --git a/glib/glibmm/main.h b/glib/glibmm/main.h
index 55f310b..345259e 100644
--- a/glib/glibmm/main.h
+++ b/glib/glibmm/main.h
@@ -70,6 +70,15 @@ private:
GPollFD gobject_;
};
+// Concerning SignalTimeout::connect_once(), SignalTimeout::connect_seconds_once()
+// and SignalIdle::connect_once():
+// See https://bugzilla.gnome.org/show_bug.cgi?id=396963 and
+// http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
+// It's recommended to replace sigc::slot<void>& by std::function<void()>& in
+// Threads::Thread::create() and ThreadPool::push() at the next ABI break.
+// Such a replacement would be a mixed blessing in SignalTimeout and SignalIdle.
+// In a single-threaded program auto-disconnection of trackable slots is safe
+// and can be useful.
class SignalTimeout
{
@@ -111,18 +120,25 @@ public:
sigc::connection connect(const sigc::slot<bool>& slot, unsigned int interval,
int priority = PRIORITY_DEFAULT);
- /** Connects a timeout handler that runs only once.
- * This method takes a function pointer to a function with a void return
- * and no parameters. After running once it is not called again.
- *
- * @see connect()
- * @param slot A slot to call when @a interval has elapsed. For example:
- * @code
- * void on_timeout_once()
- * @endcode
- * @param interval The timeout in milliseconds.
- * @param priority The priority of the new event source.
- */
+ /** Connects a timeout handler that runs only once.
+ * This method takes a function pointer to a function with a void return
+ * and no parameters. After running once it is not called again.
+ *
+ * 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(), connect_once() should only be called from
+ * the thread where the SignalTimeout object's MainContext runs. You can use,
+ * say, boost::bind() or, in C++11, std::bind() or a C++11 lambda expression
+ * instead of sigc::mem_fun().
+ *
+ * @see connect()
+ * @param slot A slot to call when @a interval has elapsed. For example:
+ * @code
+ * void on_timeout_once()
+ * @endcode
+ * @param interval The timeout in milliseconds.
+ * @param priority The priority of the new event source.
+ */
void connect_once(const sigc::slot<void>& slot, unsigned int interval,
int priority = PRIORITY_DEFAULT);
@@ -159,20 +175,27 @@ public:
sigc::connection connect_seconds(const sigc::slot<bool>& slot, unsigned int interval,
int priority = PRIORITY_DEFAULT);
- /** Connects a timeout handler that runs only once with whole second
- * granularity.
- *
- * This method takes a function pointer to a function with a void return
- * and no parameters. After running once it is not called again.
- *
- * @see connect_seconds()
- * @param slot A slot to call when @a interval has elapsed. For example:
- * @code
- * void on_timeout_once()
- * @endcode
- * @param interval The timeout in seconds.
- * @param priority The priority of the new event source.
- */
+ /** Connects a timeout handler that runs only once with whole second
+ * granularity.
+ *
+ * This method takes a function pointer to a function with a void return
+ * and no parameters. After running once it is not called again.
+ *
+ * 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(), connect_seconds_once() should only be called from
+ * the thread where the SignalTimeout object's MainContext runs. You can use,
+ * say, boost::bind() or, in C++11, std::bind() or a C++11 lambda expression
+ * instead of sigc::mem_fun().
+ *
+ * @see connect_seconds()
+ * @param slot A slot to call when @a interval has elapsed. For example:
+ * @code
+ * void on_timeout_once()
+ * @endcode
+ * @param interval The timeout in seconds.
+ * @param priority The priority of the new event source.
+ */
void connect_seconds_once(const sigc::slot<void>& slot, unsigned int interval,
int priority = PRIORITY_DEFAULT);
@@ -210,17 +233,24 @@ public:
*/
sigc::connection connect(const sigc::slot<bool>& slot, int priority = PRIORITY_DEFAULT_IDLE);
- /** Connects an idle handler that runs only once.
- * This method takes a function pointer to a function with a void return
- * and no parameters. After running once it is not called again.
- *
- * @see connect()
- * @param slot A slot to call when the main loop is idle. For example:
- * @code
- * void on_idle_once()
- * @endcode
- * @param priority The priority of the new event source.
- */
+ /** Connects an idle handler that runs only once.
+ * This method takes a function pointer to a function with a void return
+ * and no parameters. After running once it is not called again.
+ *
+ * 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(), connect_once() should only be called from
+ * the thread where the SignalIdle object's MainContext runs. You can use,
+ * say, boost::bind() or, in C++11, std::bind() or a C++11 lambda expression
+ * instead of sigc::mem_fun().
+ *
+ * @see connect()
+ * @param slot A slot to call when the main loop is idle. For example:
+ * @code
+ * void on_idle_once()
+ * @endcode
+ * @param priority The priority of the new event source.
+ */
void connect_once(const sigc::slot<void>& slot, int priority = PRIORITY_DEFAULT_IDLE);
private:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]