|
From: Frank M. H. <fm...@us...> - 2007-03-05 14:52:47
|
Update of /cvsroot/boost-sandbox/boost-sandbox/boost/thread_safe_signals/detail In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv16902/thread_safe_signals/detail Modified Files: signal_template.hpp slot_call_iterator.hpp slot_template.hpp Log Message: Restored explicit slot-to-slot tracking, since implicit version only detects slot expiration on invocation. Index: slot_call_iterator.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/thread_safe_signals/detail/slot_call_iterator.hpp,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- slot_call_iterator.hpp 2 Mar 2007 22:04:47 -0000 1.23 +++ slot_call_iterator.hpp 5 Mar 2007 14:52:46 -0000 1.24 @@ -29,95 +29,97 @@ namespace boost { namespace signalslib { namespace detail { - // Generates a slot call iterator. Essentially, this is an iterator that: - // - skips over disconnected slots in the underlying list - // - calls the connected slots when dereferenced - // - caches the result of calling the slots - template<typename Function, typename Iterator, typename ConnectionBody> - class slot_call_iterator_t - : public boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>, - typename Function::result_type, - boost::single_pass_traversal_tag, - typename Function::result_type const&> - { - typedef boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>, + // Generates a slot call iterator. Essentially, this is an iterator that: + // - skips over disconnected slots in the underlying list + // - calls the connected slots when dereferenced + // - caches the result of calling the slots + template<typename Function, typename Iterator, typename ConnectionBody> + class slot_call_iterator_t + : public boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>, typename Function::result_type, boost::single_pass_traversal_tag, typename Function::result_type const&> - inherited; + { + typedef boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>, + typename Function::result_type, + boost::single_pass_traversal_tag, + typename Function::result_type const&> + inherited; - typedef typename Function::result_type result_type; + typedef typename Function::result_type result_type; - friend class boost::iterator_core_access; + friend class boost::iterator_core_access; - public: - slot_call_iterator_t(Iterator iter_in, Iterator end_in, Function f, - boost::optional<result_type> &c): - iter(iter_in), end(end_in), f(f), - cache(&c), callable_iter(end_in) - { - lockNextCallable(); - } + public: + slot_call_iterator_t(Iterator iter_in, Iterator end_in, Function f, + boost::optional<result_type> &c): + iter(iter_in), end(end_in), f(f), + cache(&c), callable_iter(end_in) + { + lockNextCallable(); + } - typename inherited::reference - dereference() const - { - if (!(*cache)) { - try - { - cache->reset(f(*iter)); - } - catch(const bad_weak_ptr &err) - { - (*iter)->nolock_disconnect(); - throw; + typename inherited::reference + dereference() const + { + if (!(*cache)) { + try + { + cache->reset(f(*iter)); + } + catch(const bad_weak_ptr &err) + { + (*iter)->disconnect(); + throw; + } } + return cache->get(); } - return cache->get(); - } - - void increment() - { - ++iter; - lockNextCallable(); - cache->reset(); - } - bool equal(const slot_call_iterator_t& other) const - { - return iter == other.iter; - } - - private: - typedef typename ConnectionBody::mutex_type::scoped_lock lock_type; + void increment() + { + ++iter; + lockNextCallable(); + cache->reset(); + } - void lockNextCallable() const - { - if(iter == callable_iter) + bool equal(const slot_call_iterator_t& other) const { - return; + return iter == other.iter; } - for(;iter != end; ++iter) + + private: + typedef typename ConnectionBody::mutex_type::scoped_lock lock_type; + + void lockNextCallable() const { - lock_type lock((*iter)->mutex); - if((*iter)->nolock_nograb_blocked() == false) + if(iter == callable_iter) { - callable_iter = iter; - break; + return; + } + for(;iter != end; ++iter) + { + lock_type lock((*iter)->mutex); + tracked_ptrs = (*iter)->nolock_grab_tracked_objects(); + if((*iter)->nolock_nograb_blocked() == false) + { + callable_iter = iter; + break; + } + } + if(iter == end) + { + callable_iter = end; } } - if(iter == end) - { - callable_iter = end; - } - } - mutable Iterator iter; - Iterator end; - Function f; - optional<result_type>* cache; - mutable Iterator callable_iter; - }; + mutable Iterator iter; + Iterator end; + Function f; + optional<result_type>* cache; + mutable Iterator callable_iter; + mutable typename slot_base::locked_container_type tracked_ptrs; + }; } // end namespace detail } // end namespace BOOST_SIGNALS_NAMESPACE } // end namespace boost Index: signal_template.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/thread_safe_signals/detail/signal_template.hpp,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- signal_template.hpp 2 Mar 2007 16:00:39 -0000 1.42 +++ signal_template.hpp 5 Mar 2007 14:52:46 -0000 1.43 @@ -264,12 +264,12 @@ result_type m_invoke(const connection_body_type &connectionBody, const signalslib::detail::unusable *resolver) const { - connectionBody->slot(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS)); + connectionBody->slot.slot_function()(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS)); return signalslib::detail::unusable(); } result_type m_invoke(const connection_body_type &connectionBody, ...) const { - return connectionBody->slot(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS)); + return connectionBody->slot.slot_function()(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS)); } }; // a struct used to optimize (minimize) the number of shared_ptrs that need to be created Index: slot_template.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/thread_safe_signals/detail/slot_template.hpp,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- slot_template.hpp 2 Mar 2007 22:04:47 -0000 1.7 +++ slot_template.hpp 5 Mar 2007 14:52:46 -0000 1.8 @@ -48,6 +48,18 @@ BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)(const F& f): _slot_function(signalslib::detail::get_invocable_slot(f, signalslib::detail::tag_type(f))) { } + // copy constructors + template<BOOST_SIGNAL_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS_NUM_ARGS, Other), typename OtherSlotFunction> + BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)(const BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS) + <BOOST_SIGNAL_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS_NUM_ARGS, Other), OtherSlotFunction> &other_slot): + signalslib::detail::slot_base(other_slot), _slot_function(other_slot._slot_function) + { + } + template<typename Signature, typename OtherSlotFunction> + BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)(const slot<Signature, OtherSlotFunction> &other_slot): + signalslib::detail::slot_base(other_slot), _slot_function(other_slot._slot_function) + { + } // bind syntactic sugar // ArgTypeN argN #define BOOST_SLOT_BINDING_ARG_DECL(z, n, data) \ @@ -63,6 +75,7 @@ #undef BOOST_SLOT_MAX_BINDING_ARGS #undef BOOST_SLOT_BINDING_ARG_DECL #undef BOOST_SLOT_BINDING_CONSTRUCTOR + // invocation R operator()(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS)) { locked_container_type locked_objects = lock(); @@ -73,18 +86,30 @@ locked_container_type locked_objects = lock(); return _slot_function(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS)); } + // tracking BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)& track(const weak_ptr<void> &tracked) { _trackedObjects.push_back(tracked); return *this; } + BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)& track(const slot_base &slot) + { + tracked_container_type::const_iterator it; + for(it = slot.tracked_objects().begin(); it != slot.tracked_objects().end(); ++it) + { + track(*it); + } + return *this; + } BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)& track(const signalslib::detail::signal_base &signal) { // call base class function, since it is a friend of signal_base and can call lock_pimpl() track_signal(signal); return *this; } + const slot_function_type& slot_function() const {return _slot_function;} + slot_function_type& slot_function() {return _slot_function;} private: SlotFunction _slot_function; }; |