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