[libsigc++2] trackable: Avoid calling the same callback function twice
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsigc++2] trackable: Avoid calling the same callback function twice
- Date: Tue, 22 Feb 2011 10:08:19 +0000 (UTC)
commit 18d3559c84c27549b312e2100d9918ec540bda2b
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Tue Feb 22 10:27:40 2011 +0100
trackable: Avoid calling the same callback function twice
* sigc++/trackable.cc: Invalidate a callback function entry in
trackable_callback_list::remove_callback() when the list is being cleared.
Bug 589202.
ChangeLog | 8 ++++++++
sigc++/trackable.cc | 19 ++++++++++++-------
2 files changed, 20 insertions(+), 7 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 39f7558..ffd0e60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2011-02-22 Kjell Ahlstedt <kjell ahlstedt bredband net>
+
+ trackable: Avoid calling the same callback function twice
+
+ * sigc++/trackable.cc: Invalidate a callback function entry in
+ trackable_callback_list::remove_callback() when the list is being cleared.
+ Bug 589202.
+
2011-02-04 Kalev Lember <kalev smartlink ee>
Fix the build with GCC 4.6
diff --git a/sigc++/trackable.cc b/sigc++/trackable.cc
index a4f1f54..f7e4cb7 100644
--- a/sigc++/trackable.cc
+++ b/sigc++/trackable.cc
@@ -86,7 +86,8 @@ trackable_callback_list::~trackable_callback_list()
clearing_ = true;
for (callback_list::iterator i = callbacks_.begin(); i != callbacks_.end(); ++i)
- (*i).func_((*i).data_);
+ if ((*i).func_)
+ (*i).func_((*i).data_);
}
void trackable_callback_list::add_callback(void* data, func_destroy_notify func)
@@ -102,7 +103,8 @@ void trackable_callback_list::clear()
clearing_ = true;
for (callback_list::iterator i = callbacks_.begin(); i != callbacks_.end(); ++i)
- (*i).func_((*i).data_);
+ if ((*i).func_)
+ (*i).func_((*i).data_);
callbacks_.clear();
@@ -111,17 +113,20 @@ void trackable_callback_list::clear()
void trackable_callback_list::remove_callback(void* data)
{
- if (clearing_) return; // No circular notices
-
for (callback_list::iterator i = callbacks_.begin(); i != callbacks_.end(); ++i)
- if ((*i).data_ == data)
+ if ((*i).data_ == data && (*i).func_ != 0)
{
- callbacks_.erase(i);
+ //Don't remove a list element while the list is being cleared.
+ //It could invalidate the iterator in ~trackable_callback_list() or clear().
+ //But it may be necessary to invalidate the callback. See bug 589202.
+ if (clearing_)
+ (*i).func_ = 0;
+ else
+ callbacks_.erase(i);
return;
}
}
} /* namespace internal */
-
} /* namespace sigc */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]