Boost logo

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