[libsigcplusplus] signal_impl::clear(): Don't clear the slot list during signal emission



commit 65edaa5f036ad4a1d9ac5b0b8e8ed6e51524c096
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Mon Jul 17 09:59:46 2017 +0200

    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

 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


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