https://github.com/boostorg/signals2/issues/70 From 2ba258f7b465e7bde14663ca3a966019b4ec3694 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Sat, 30 Dec 2023 14:34:58 -0500 Subject: [PATCH] Fix disconnect by slot when the slot is another signal. --- a/boost/signals2/detail/signal_template.hpp +++ b/boost/signals2/detail/signal_template.hpp @@ -103,9 +103,9 @@ namespace boost BOOST_SIGNALS2_FORWARDED_ARGS(BOOST_SIGNALS2_NUM_ARGS)); } template - bool operator==(const T &other) const + bool contains(const T &other) const { - return _fun == other; + return _fun.contains(other); } private: BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(BOOST_SIGNALS2_NUM_ARGS)() @@ -115,6 +115,8 @@ namespace boost boost::shared_ptr _connection; }; + template + class BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS); template class BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS); @@ -150,6 +152,8 @@ namespace boost typedef GroupCompare group_compare_type; typedef typename detail::slot_call_iterator_t > slot_call_iterator; + typedef detail::BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) + weak_signal_type; BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const combiner_type &combiner_arg, const group_compare_type &group_compare): @@ -531,13 +535,20 @@ namespace boost { (*it)->nolock_disconnect(lock); }else - { - // check for wrapped extended slot + { // check for wrapped extended slot bound_extended_slot_function_type *fp; fp = (*it)->slot().slot_function().template target(); - if(fp && function_equal(*fp, slot)) + if(fp && fp->contains(slot)) { (*it)->nolock_disconnect(lock); + }else + { // check for wrapped signal + weak_signal_type *fp; + fp = (*it)->slot().slot_function().template target(); + if(fp && fp->contains(slot)) + { + (*it)->nolock_disconnect(lock); + } } } } @@ -588,8 +599,6 @@ namespace boost const boost::shared_ptr _mutex; }; - template - class BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS); } template @@ -603,8 +612,7 @@ namespace boost typedef detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) impl_class; public: - typedef detail::BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) - weak_signal_type; + typedef typename impl_class::weak_signal_type weak_signal_type; friend class detail::BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) ; @@ -746,12 +754,24 @@ namespace boost using std::swap; swap(_pimpl, other._pimpl); } + bool operator==(const BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) & other) const + { + return _pimpl.get() == other._pimpl.get(); + } protected: virtual shared_ptr lock_pimpl() const { return _pimpl; } private: + // explicit private copy constructor to avoid compiler trying to do implicit conversions to signal + explicit BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)( + const BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) & other) BOOST_NOEXCEPT + { + // noncopyable + BOOST_ASSERT(false); + } + shared_ptr _pimpl; }; @@ -802,6 +822,16 @@ namespace boost shared_pimpl(_weak_pimpl.lock()); return (*shared_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS)); } + bool contains(const BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) + &signal) const + { + return _weak_pimpl.lock().get() == signal._pimpl.get(); + } + template + bool contains(const T&) const + { + return false; + } private: boost::weak_ptr > _weak_pimpl;