[libsigcplusplus] signal_impl_holder: Split into this and signal_exec_holder.



commit ff08099a41a9c8019aa0004c76073e0d91fce5c3
Author: Murray Cumming <murrayc murrayc com>
Date:   Sat Apr 16 21:14:54 2016 +0200

    signal_impl_holder: Split into this and signal_exec_holder.
    
    And use just signal_exec_holder in signal_impl::clear(),
    instead of trying to take create a shared_ptr to this while
    this is being destroyed.
    
    Bug #764935

 sigc++/signal_base.cc |    2 +-
 sigc++/signal_base.h  |   32 +++++++++++++++++++++++++++-----
 2 files changed, 28 insertions(+), 6 deletions(-)
---
diff --git a/sigc++/signal_base.cc b/sigc++/signal_base.cc
index 3ad33ae..94841be 100644
--- a/sigc++/signal_base.cc
+++ b/sigc++/signal_base.cc
@@ -65,7 +65,7 @@ signal_impl::clear()
   // Don't let signal_impl::notify() erase the slots. It would invalidate the
   // iterator in the following loop.
   const bool saved_deferred = deferred_;
-  signal_impl_holder exec(shared_from_this());
+  signal_impl_exec_holder(this);
 
   // Disconnect all connected slots before they are deleted.
   // signal_impl::notify() will be called and delete the self_and_iter structs.
diff --git a/sigc++/signal_base.h b/sigc++/signal_base.h
index d3b19a2..de72647 100644
--- a/sigc++/signal_base.h
+++ b/sigc++/signal_base.h
@@ -181,6 +181,31 @@ private:
   bool deferred_;
 };
 
+struct SIGC_API signal_impl_exec_holder
+{
+  /** Increments the execution counter of the parent sigc::signal_impl object.
+   * @param sig The parent sigc::signal_impl object.
+   */
+  inline signal_impl_exec_holder(signal_impl* sig) noexcept
+  : sig_(sig)
+  {
+    sig_->reference_exec();
+  }
+
+  signal_impl_exec_holder(const signal_impl_exec_holder& src) = delete;
+  signal_impl_exec_holder operator=(const signal_impl_exec_holder& src) = delete;
+
+  signal_impl_exec_holder(signal_impl_exec_holder&& src) = delete;
+  signal_impl_exec_holder operator=(signal_impl_exec_holder&& src) = delete;
+
+  /// Decrements the reference and execution counter of the parent sigc::signal_impl object.
+  inline ~signal_impl_exec_holder() { sig_->unreference_exec(); }
+
+protected:
+  /// The parent sigc::signal_impl object.
+  signal_impl* sig_;
+};
+
 /// Exception safe sweeper for cleaning up invalid slots on the slot list.
 struct SIGC_API signal_impl_holder
 {
@@ -188,9 +213,8 @@ struct SIGC_API signal_impl_holder
    * @param sig The parent sigc::signal_impl object.
    */
   inline signal_impl_holder(const std::shared_ptr<signal_impl>& sig) noexcept
-  : sig_(sig)
+  : sig_(sig), exec_holder_(sig.get())
   {
-    sig_->reference_exec();
   }
 
   signal_impl_holder(const signal_impl_holder& src) = delete;
@@ -199,12 +223,10 @@ struct SIGC_API signal_impl_holder
   signal_impl_holder(signal_impl_holder&& src) = delete;
   signal_impl_holder operator=(signal_impl_holder&& src) = delete;
 
-  /// Decrements the reference and execution counter of the parent sigc::signal_impl object.
-  inline ~signal_impl_holder() { sig_->unreference_exec(); }
-
 protected:
   /// The parent sigc::signal_impl object.
   const std::shared_ptr<signal_impl> sig_;
+  signal_impl_exec_holder exec_holder_;
 };
 
 } /* namespace internal */


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