diff options
author | Murray Cumming <murrayc@murrayc.com> | 2016-04-16 21:14:54 +0200 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2016-04-24 21:01:06 +0200 |
commit | ff08099a41a9c8019aa0004c76073e0d91fce5c3 (patch) | |
tree | 802b9faeed366f19eb3b12e44e4b03573dfd5b35 | |
parent | a23850a062a2346fbe434fa8b4f7cb85a94344c7 (diff) | |
download | sigc++-ff08099a41a9c8019aa0004c76073e0d91fce5c3.tar.gz |
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
-rw-r--r-- | sigc++/signal_base.cc | 2 | ||||
-rw-r--r-- | 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 */ |