diff options
author | Murray Cumming <murrayc@murrayc.com> | 2016-03-03 13:46:09 +0100 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2016-03-03 22:46:07 +0100 |
commit | 06e86e782035b187ccd9509af0d82276dfc21698 (patch) | |
tree | d6bd5357260e49a947ddff808bcc9464a920b819 | |
parent | c9834e67772cbe9f3af6d44f828392c556b37a00 (diff) | |
download | sigc++-06e86e782035b187ccd9509af0d82276dfc21698.tar.gz |
signal_base: clear signal_impl in its own destructor.
This deals with some TODO comments.
This patch is based on a suggestion from Kjell Ahlstedt:
See https://bugzilla.gnome.org/show_bug.cgi?id=167714#c14
-rw-r--r-- | sigc++/signal_base.cc | 29 | ||||
-rw-r--r-- | sigc++/signal_base.h | 1 |
2 files changed, 15 insertions, 15 deletions
diff --git a/sigc++/signal_base.cc b/sigc++/signal_base.cc index bbb1955..1bf12c4 100644 --- a/sigc++/signal_base.cc +++ b/sigc++/signal_base.cc @@ -37,6 +37,19 @@ signal_impl::signal_impl() : ref_count_(0), exec_count_(0), deferred_(false) {} +signal_impl::~signal_impl() +{ + // unreference() must not call ~signal_impl() while clear() is executing. + ++ref_count_; + + // Disconnect all slots before *this is deleted. + clear(); + + // Now ref_count_ can be cleared again (not really necessary), but don't do it + // with a call to unreference(). That would invoke ~signal_impl() recursively. + --ref_count_; +} + // only MSVC needs this to guarantee that all new/delete are executed from the DLL module #ifdef SIGC_NEW_DELETE_IN_LIBRARY_ONLY void* signal_impl::operator new(size_t size_) @@ -191,11 +204,6 @@ signal_base::~signal_base() { if (impl_) { - // Disconnect all slots before impl_ is deleted. - // TODO: Move the signal_impl::clear() call to ~signal_impl() when ABI can be broken. - if (impl_->ref_count_ == 1) - impl_->clear(); - impl_->unreference(); } } @@ -259,13 +267,9 @@ signal_base& signal_base::operator=(const signal_base& src) if (impl_) { - // Disconnect all slots before impl_ is deleted. - // TODO: Move the signal_impl::clear() call to ~signal_impl() when ABI can be broken. - if (impl_->ref_count_ == 1) - impl_->clear(); - impl_->unreference(); } + impl_ = src.impl(); impl_->reference(); return *this; @@ -277,11 +281,6 @@ signal_base& signal_base::operator=(signal_base&& src) if (impl_) { - // Disconnect all slots before impl_ is deleted. - // TODO: Move the signal_impl::clear() call to ~signal_impl() when ABI can be broken. - if (impl_->ref_count_ == 1) - impl_->clear(); - impl_->unreference(); } diff --git a/sigc++/signal_base.h b/sigc++/signal_base.h index 94037ca..d19a341 100644 --- a/sigc++/signal_base.h +++ b/sigc++/signal_base.h @@ -50,6 +50,7 @@ struct SIGC_API signal_impl : public notifiable typedef slot_list::const_iterator const_iterator_type; signal_impl(); + ~signal_impl(); signal_impl(const signal_impl& src) = delete; signal_impl& operator=(const signal_impl& src) = delete; |