[Boost-bugs] [Boost C++ Libraries] #7015: boost::signals::connection with shared_ptr to connected signal

Subject: [Boost-bugs] [Boost C++ Libraries] #7015: boost::signals::connection with shared_ptr to connected signal
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-06-22 15:27:26


#7015: boost::signals::connection with shared_ptr to connected signal
------------------------------------------------+---------------------------
 Reporter: Nick Mayer <nick.mayer@…> | Owner: dgregor
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: signals
  Version: Boost 1.49.0 | Severity: Problem
 Keywords: signals connection shared_ptr |
------------------------------------------------+---------------------------
 If you create a connection with a shared_ptr that controls the lifespan of
 the signal an access violation occurs on disconnection if that is the last
 remaining reference to the object.

 {{{
 #!c++
 class Child : public boost::signals::trackable
 {
 public:
     Child(){}

     virtual ~Child(){}

     void callback( int a, int b )
     {
         printf( "Child::callback( %d, %d )\n", a, b );
     }

     boost::signal<void(int)> mSignal;
 };

 int main(int argc, char* argv[])
 {
     boost::shared_ptr<Child> c( new Child );
     boost::signals::connection con;
     con = c->mSignal.connect( boost::bind( &Child::callback, c, 1, _1 ) );
     c->mSignal( 5 );
     c.reset();

     // The connection is the only thing keeping it alive. When we
 disconnect
     // it will also destroy the signal. This causes a memory access
 violation
     // when the signal containing the list of connections gets deleted
 while
     // removing an item from that list.
     con.disconnect();
 }
 }}}

 The fix is to prevent the slot from going out of scope during the act of
 disconnecting from the signal.
 {{{
 diff --git a/libs/signals/src/signal_base.cpp
 b/libs/signals/src/signal_base.cpp
 index 759672d..918e811 100644
 --- a/libs/signals/src/signal_base.cpp
 +++ b/libs/signals/src/signal_base.cpp
 @@ -143,8 +143,14 @@ namespace boost {
              self->flags.delayed_disconnect = true;
            }
            else {
              // Just remove the slot now, it's safe
 + // There is a chance that the binding has the last reference
 to
 + // the signal, and destroying it will destroy the signal. To
 prevent
 + // this from causing a problem keep a local copy of the
 binding
 + // during it's removal from the slot list.
 + boost::any keep_alive = (*slot)->second;
              self->slots_.erase(*slot);
 + return;
            }
          }
        }
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/7015>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:09 UTC