diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2017-07-17 09:59:46 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2017-07-17 09:59:46 +0200 |
commit | 65edaa5f036ad4a1d9ac5b0b8e8ed6e51524c096 (patch) | |
tree | c17694378a12dcddfde4b20360970f949c7f24b8 | |
parent | d1a04ee9b87bdac0a1d295710f49dd39cb6120e1 (diff) | |
download | sigc++-65edaa5f036ad4a1d9ac5b0b8e8ed6e51524c096.tar.gz |
signal_impl::clear(): Don't clear the slot list during signal emission
If signal_impl::clear() is called during signal emission, don't call
slots_.clear(). Let signal_impl::sweep() erase all slots after the signal
emission. Bug 784550
-rw-r--r-- | sigc++/signal_base.cc | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/sigc++/signal_base.cc b/sigc++/signal_base.cc index 2038568..875a3ae 100644 --- a/sigc++/signal_base.cc +++ b/sigc++/signal_base.cc @@ -68,6 +68,7 @@ signal_impl::clear() // Don't call shared_from_this() here. clear() is called from the destructor. // When the destructor is executing, shared_ptr's use_count has reached 0, // and it's no longer possible to get a shared_ptr to this. + const bool during_signal_emission = exec_count_ > 0; const bool saved_deferred = deferred_; signal_impl_exec_holder exec(this); @@ -76,9 +77,15 @@ signal_impl::clear() for (auto& slot : slots_) slot.disconnect(); - deferred_ = saved_deferred; - - slots_.clear(); + // Don't clear slots_ during signal emission. Provided deferred_ is true, + // sweep() will be called from ~signal_impl_holder() after signal emission, + // and it will erase all disconnected slots. + // https://bugzilla.gnome.org/show_bug.cgi?id=784550 + if (!during_signal_emission) + { + deferred_ = saved_deferred; + slots_.clear(); + } } signal_impl::size_type |