|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r61278 - in branches/release/boost/signals2: . detail
From: fmhess_at_[hidden]
Date: 2010-04-14 16:30:38
Author: fmhess
Date: 2010-04-14 16:30:37 EDT (Wed, 14 Apr 2010)
New Revision: 61278
URL: http://svn.boost.org/trac/boost/changeset/61278
Log:
Merged from trunk to release. Fixes #4089.
Properties modified:
branches/release/boost/signals2/ (props changed)
Text files modified:
branches/release/boost/signals2/detail/signal_template.hpp | 27 ++++++++++++++++-----------
1 files changed, 16 insertions(+), 11 deletions(-)
Modified: branches/release/boost/signals2/detail/signal_template.hpp
==============================================================================
--- branches/release/boost/signals2/detail/signal_template.hpp (original)
+++ branches/release/boost/signals2/detail/signal_template.hpp 2010-04-14 16:30:37 EDT (Wed, 14 Apr 2010)
@@ -229,7 +229,7 @@
unique_lock<mutex_type> list_lock(_mutex);
// only clean up if it is safe to do so
if(_shared_state.unique())
- nolock_cleanup_connections(false);
+ nolock_cleanup_connections(false, 1);
/* Make a local copy of _shared_state while holding mutex, so we are
thread safe against the combiner or connection list getting modified
during invocation. */
@@ -253,7 +253,7 @@
unique_lock<mutex_type> list_lock(_mutex);
// only clean up if it is safe to do so
if(_shared_state.unique())
- nolock_cleanup_connections(false);
+ nolock_cleanup_connections(false, 1);
/* Make a local copy of _shared_state while holding mutex, so we are
thread safe against the combiner or connection list getting modified
during invocation. */
@@ -412,12 +412,15 @@
};
// clean up disconnected connections
- void nolock_cleanup_connections(bool grab_tracked,
- const typename connection_list_type::iterator &begin, bool break_on_connected = false) const
+ void nolock_cleanup_connections_from(bool grab_tracked,
+ const typename connection_list_type::iterator &begin, unsigned count = 0) const
{
BOOST_ASSERT(_shared_state.unique());
typename connection_list_type::iterator it;
- for(it = begin; it != _shared_state->connection_bodies().end();)
+ unsigned i;
+ for(it = begin, i = 0;
+ it != _shared_state->connection_bodies().end() && (count == 0 || i < count);
+ ++i)
{
bool connected;
{
@@ -432,13 +435,12 @@
}else
{
++it;
- if(break_on_connected) break;
}
}
_garbage_collector_it = it;
}
// clean up a few connections in constant time
- void nolock_cleanup_connections(bool grab_tracked) const
+ void nolock_cleanup_connections(bool grab_tracked, unsigned count) const
{
BOOST_ASSERT(_shared_state.unique());
typename connection_list_type::iterator begin;
@@ -449,7 +451,7 @@
{
begin = _garbage_collector_it;
}
- nolock_cleanup_connections(grab_tracked, begin, true);
+ nolock_cleanup_connections_from(grab_tracked, begin, count);
}
/* Make a new copy of the slot list if it is currently being read somewhere else
*/
@@ -458,10 +460,13 @@
if(_shared_state.unique() == false)
{
_shared_state.reset(new invocation_state(*_shared_state, _shared_state->connection_bodies()));
- nolock_cleanup_connections(true, _shared_state->connection_bodies().begin());
+ nolock_cleanup_connections_from(true, _shared_state->connection_bodies().begin());
}else
{
- nolock_cleanup_connections(true);
+ /* We need to try and check more than just 1 connection here to avoid corner
+ cases where certain repeated connect/disconnect patterns cause the slot
+ list to grow without limit. */
+ nolock_cleanup_connections(true, 2);
}
}
// force a full cleanup of the connection list
@@ -478,7 +483,7 @@
{
_shared_state.reset(new invocation_state(*_shared_state, _shared_state->connection_bodies()));
}
- nolock_cleanup_connections(true, _shared_state->connection_bodies().begin());
+ nolock_cleanup_connections_from(false, _shared_state->connection_bodies().begin());
}
shared_ptr<invocation_state> get_readable_state() const
{
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk