summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMurray Cumming <murrayc@murrayc.com>2016-03-03 13:46:09 +0100
committerMurray Cumming <murrayc@murrayc.com>2016-03-03 22:46:07 +0100
commit06e86e782035b187ccd9509af0d82276dfc21698 (patch)
treed6bd5357260e49a947ddff808bcc9464a920b819
parentc9834e67772cbe9f3af6d44f828392c556b37a00 (diff)
downloadsigc++-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.cc29
-rw-r--r--sigc++/signal_base.h1
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;