diff options
author | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2011-02-22 10:27:40 +0100 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2011-02-22 11:04:03 +0100 |
commit | 18d3559c84c27549b312e2100d9918ec540bda2b (patch) | |
tree | 3de820ecdb27232e012444b8622f17a5458ce8b5 | |
parent | faabe1f90c142a5ea836884a04c0eef250e69f94 (diff) | |
download | sigc++-18d3559c84c27549b312e2100d9918ec540bda2b.tar.gz |
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.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | sigc++/trackable.cc | 19 |
2 files changed, 20 insertions, 7 deletions
@@ -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 */ |