diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:30:07 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:32:57 +0900 |
commit | 71d216b90256936a9638f325af9bc69d720e75de (patch) | |
tree | 9c5f682d341c7c88ad0c8e3d4b262e00b6fb691a /boost/signals2/detail/slot_call_iterator.hpp | |
parent | 733b5d5ae2c5d625211e2985ac25728ac3f54883 (diff) | |
download | boost-71d216b90256936a9638f325af9bc69d720e75de.tar.gz boost-71d216b90256936a9638f325af9bc69d720e75de.tar.bz2 boost-71d216b90256936a9638f325af9bc69d720e75de.zip |
Imported Upstream version 1.59.0
Change-Id: I2dde00f4eca71df3eea9d251dcaecde18a6c90a5
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/signals2/detail/slot_call_iterator.hpp')
-rw-r--r-- | boost/signals2/detail/slot_call_iterator.hpp | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/boost/signals2/detail/slot_call_iterator.hpp b/boost/signals2/detail/slot_call_iterator.hpp index 9dbbb3c9b5..ee8426f474 100644 --- a/boost/signals2/detail/slot_call_iterator.hpp +++ b/boost/signals2/detail/slot_call_iterator.hpp @@ -21,6 +21,8 @@ #include <boost/signals2/slot_base.hpp> #include <boost/signals2/detail/auto_buffer.hpp> #include <boost/signals2/detail/unique_lock.hpp> +#include <boost/type_traits/add_const.hpp> +#include <boost/type_traits/add_reference.hpp> #include <boost/weak_ptr.hpp> namespace boost { @@ -33,14 +35,37 @@ namespace boost { slot_call_iterator_cache(const Function &f_arg): f(f_arg), connected_slot_count(0), - disconnected_slot_count(0) + disconnected_slot_count(0), + m_active_slot(0) {} + + ~slot_call_iterator_cache() + { + if(m_active_slot) + { + garbage_collecting_lock<connection_body_base> lock(*m_active_slot); + m_active_slot->dec_slot_refcount(lock); + } + } + + template<typename M> + void set_active_slot(garbage_collecting_lock<M> &lock, + connection_body_base *active_slot) + { + if(m_active_slot) + m_active_slot->dec_slot_refcount(lock); + m_active_slot = active_slot; + if(m_active_slot) + m_active_slot->inc_slot_refcount(lock); + } + optional<ResultType> result; typedef auto_buffer<void_shared_ptr_variant, store_n_objects<10> > tracked_ptrs_type; tracked_ptrs_type tracked_ptrs; Function f; unsigned connected_slot_count; unsigned disconnected_slot_count; + connection_body_base *m_active_slot; }; // Generates a slot call iterator. Essentially, this is an iterator that: @@ -52,21 +77,23 @@ namespace boost { : 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&> + typename boost::add_const<typename boost::add_reference<typename Function::result_type>::type>::type > { 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&> + typename boost::add_const<typename boost::add_reference<typename Function::result_type>::type>::type > inherited; typedef typename Function::result_type result_type; + typedef slot_call_iterator_cache<result_type, Function> cache_type; + friend class boost::iterator_core_access; public: slot_call_iterator_t(Iterator iter_in, Iterator end_in, - slot_call_iterator_cache<result_type, Function> &c): + cache_type &c): iter(iter_in), end(end_in), cache(&c), callable_iter(end_in) { @@ -103,19 +130,39 @@ namespace boost { } private: - typedef unique_lock<connection_body_base> lock_type; + typedef garbage_collecting_lock<connection_body_base> lock_type; + void set_callable_iter(lock_type &lock, Iterator newValue) const + { + callable_iter = newValue; + if(callable_iter == end) + cache->set_active_slot(lock, 0); + else + cache->set_active_slot(lock, (*callable_iter).get()); + } + void lock_next_callable() const { if(iter == callable_iter) { return; } + if(iter == end) + { + if(callable_iter != end) + { + lock_type lock(**callable_iter); + set_callable_iter(lock, end); + return; + } + } + // we're only locking the first connection body, + // but it doesn't matter they all use the same mutex + lock_type lock(**iter); for(;iter != end; ++iter) { cache->tracked_ptrs.clear(); - lock_type lock(**iter); - (*iter)->nolock_grab_tracked_objects(std::back_inserter(cache->tracked_ptrs)); + (*iter)->nolock_grab_tracked_objects(lock, std::back_inserter(cache->tracked_ptrs)); if((*iter)->nolock_nograb_connected()) { ++cache->connected_slot_count; @@ -125,19 +172,19 @@ namespace boost { } if((*iter)->nolock_nograb_blocked() == false) { - callable_iter = iter; + set_callable_iter(lock, iter); break; } } if(iter == end) { - callable_iter = end; + set_callable_iter(lock, end); } } mutable Iterator iter; Iterator end; - slot_call_iterator_cache<result_type, Function> *cache; + cache_type *cache; mutable Iterator callable_iter; }; } // end namespace detail |