summaryrefslogtreecommitdiff
path: root/boost/signals2/detail/slot_call_iterator.hpp
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:30:07 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:32:57 +0900
commit71d216b90256936a9638f325af9bc69d720e75de (patch)
tree9c5f682d341c7c88ad0c8e3d4b262e00b6fb691a /boost/signals2/detail/slot_call_iterator.hpp
parent733b5d5ae2c5d625211e2985ac25728ac3f54883 (diff)
downloadboost-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.hpp67
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