summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMurray Cumming <murrayc@murrayc.com>2016-04-16 21:14:54 +0200
committerMurray Cumming <murrayc@murrayc.com>2016-04-24 21:01:06 +0200
commitff08099a41a9c8019aa0004c76073e0d91fce5c3 (patch)
tree802b9faeed366f19eb3b12e44e4b03573dfd5b35
parenta23850a062a2346fbe434fa8b4f7cb85a94344c7 (diff)
downloadsigc++-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.cc2
-rw-r--r--sigc++/signal_base.h32
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 */