Skip to content

Commit ff08099

Browse files
committed
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
1 parent a23850a commit ff08099

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

sigc++/signal_base.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ signal_impl::clear()
6565
// Don't let signal_impl::notify() erase the slots. It would invalidate the
6666
// iterator in the following loop.
6767
const bool saved_deferred = deferred_;
68-
signal_impl_holder exec(shared_from_this());
68+
signal_impl_exec_holder(this);
6969

7070
// Disconnect all connected slots before they are deleted.
7171
// signal_impl::notify() will be called and delete the self_and_iter structs.

sigc++/signal_base.h

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,40 @@ struct SIGC_API signal_impl
181181
bool deferred_;
182182
};
183183

184+
struct SIGC_API signal_impl_exec_holder
185+
{
186+
/** Increments the execution counter of the parent sigc::signal_impl object.
187+
* @param sig The parent sigc::signal_impl object.
188+
*/
189+
inline signal_impl_exec_holder(signal_impl* sig) noexcept
190+
: sig_(sig)
191+
{
192+
sig_->reference_exec();
193+
}
194+
195+
signal_impl_exec_holder(const signal_impl_exec_holder& src) = delete;
196+
signal_impl_exec_holder operator=(const signal_impl_exec_holder& src) = delete;
197+
198+
signal_impl_exec_holder(signal_impl_exec_holder&& src) = delete;
199+
signal_impl_exec_holder operator=(signal_impl_exec_holder&& src) = delete;
200+
201+
/// Decrements the reference and execution counter of the parent sigc::signal_impl object.
202+
inline ~signal_impl_exec_holder() { sig_->unreference_exec(); }
203+
204+
protected:
205+
/// The parent sigc::signal_impl object.
206+
signal_impl* sig_;
207+
};
208+
184209
/// Exception safe sweeper for cleaning up invalid slots on the slot list.
185210
struct SIGC_API signal_impl_holder
186211
{
187212
/** Increments the reference and execution counter of the parent sigc::signal_impl object.
188213
* @param sig The parent sigc::signal_impl object.
189214
*/
190215
inline signal_impl_holder(const std::shared_ptr<signal_impl>& sig) noexcept
191-
: sig_(sig)
216+
: sig_(sig), exec_holder_(sig.get())
192217
{
193-
sig_->reference_exec();
194218
}
195219

196220
signal_impl_holder(const signal_impl_holder& src) = delete;
@@ -199,12 +223,10 @@ struct SIGC_API signal_impl_holder
199223
signal_impl_holder(signal_impl_holder&& src) = delete;
200224
signal_impl_holder operator=(signal_impl_holder&& src) = delete;
201225

202-
/// Decrements the reference and execution counter of the parent sigc::signal_impl object.
203-
inline ~signal_impl_holder() { sig_->unreference_exec(); }
204-
205226
protected:
206227
/// The parent sigc::signal_impl object.
207228
const std::shared_ptr<signal_impl> sig_;
229+
signal_impl_exec_holder exec_holder_;
208230
};
209231

210232
} /* namespace internal */

0 commit comments

Comments
 (0)