Subject: [Boost-bugs] [Boost C++ Libraries] #7724: executing signals2::signal::connect creates many copies of the connected object
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-11-22 13:31:06
#7724: executing signals2::signal::connect creates many copies of the connected
object
----------------------------------------------------+-----------------------
Reporter: pszeptycki@⦠| Owner: fmhess
Type: Bugs | Status: new
Milestone: To Be Determined | Component: signals2
Version: Boost 1.49.0 | Severity: Problem
Keywords: signals2 connect multiple objects copy |
----------------------------------------------------+-----------------------
I am trying to figure out where is the problem, maybe what I have
implemented is incorrect or it is a bug.
When trying to connect to a signal the passed object is copied many times
and the final triggered signal executes a method on a copy of the passed
object.
Signal is the following type:
{{{
typedef signals2::signal<void (NotificationCenter::Notification)> Signal;
}}}
Following code (NotificationCenter creates a shared_ptr<> to the requested
signals):
{{{
class NotificationReceived
{
public:
int runCount;
NotificationReceived()
{
std::cout << "* Receiver CREATED" << std::endl;
runCount = 0;
}
NotificationReceived(const NotificationReceived &cSource)
{
std::cout << "* Receiver COPIED" << std::endl;
runCount = cSource.runCount;
}
~NotificationReceived()
{
std::cout << "* Receiver DELETED" << std::endl;
}
void Receive(NotificationCenter::Notification notif)
{
std::cout << std::endl << "Receive: Notification received:
" + notif.m_information << std::endl << std::endl;
runCount++;
}
};
BOOST_AUTO_TEST_CASE( test_notification_center_notify)
{
NotificationCenter nCenter(NotificationCenter::NCT_DELAYED);
NotificationReceived receiver;
NotificationCenter::Signal* sig =
nCenter.RegisterForNotification(NotificationCenter::Notification::NT_BROADCAST);
sig->connect(boost::bind(&NotificationReceived::Receive, receiver,
_1));
nCenter.BroadcastNotification(NotificationCenter::Notification(NotificationCenter::Notification::NT_BROADCAST,
"Testing"));
boost::this_thread::sleep(boost::posix_time::seconds(2));
BOOST_REQUIRE_EQUAL(receiver.runCount, 1);
}
}}}
Has following output:
{{{
* Receiver CREATED
- Queue empty - sleeping 500ms
* Receiver COPIED
* Receiver COPIED
* Receiver COPIED
* Receiver COPIED
* Receiver COPIED
* Receiver DELETED
* Receiver DELETED
* Receiver DELETED
* Receiver COPIED
* Receiver DELETED
* Receiver DELETED
* Receiver COPIED
* Receiver COPIED
* Receiver COPIED
* Receiver COPIED
* Receiver COPIED
* Receiver COPIED
* Receiver COPIED
* Receiver COPIED
* Receiver DELETED
* Receiver DELETED
* Receiver DELETED
* Receiver DELETED
* Receiver DELETED
* Receiver DELETED
* Receiver COPIED
* Receiver DELETED
* Receiver COPIED
* Receiver DELETED
* Receiver DELETED
* Receiver COPIED
* Receiver DELETED
* Receiver DELETED
- Thread waked up
- Queue not empty, searching receivers ...
- Sending notification
Receive: Notification received: Testing
- Queue empty - sleeping 500ms
- Thread waked up
- Queue empty - sleeping 500ms
- Thread waked up
- Queue empty - sleeping 500ms
* Receiver DELETED
* Receiver DELETED
*** 1 failure detected in test suite "FrameworkTests"
}}}
'''Why the "receiver" object has been copied many times and the final
method has not been executed on the original object but on a copy which
proves the check of the "runCount"?'''
I have managed to go around this problem adding a shared_ptr<>
Following code (classes the same):
{{{
NotificationCenter nCenter(NotificationCenter::NCT_DELAYED);
boost::shared_ptr<NotificationReceived> receiver(new
NotificationReceived);
NotificationCenter::Signal* sig =
nCenter.RegisterForNotification(NotificationCenter::Notification::NT_BROADCAST);
sig->connect(boost::bind(&NotificationReceived::Receive, receiver,
_1));
nCenter.BroadcastNotification(NotificationCenter::Notification(NotificationCenter::Notification::NT_BROADCAST,
"Testing"));
boost::this_thread::sleep(boost::posix_time::seconds(2));
BOOST_REQUIRE_EQUAL(receiver->runCount, 1);
}}}
Outputs what I expected also from the first example:
{{{
* Receiver CREATED
- Queue empty - sleeping 500ms
- Thread waked up
- Queue not empty, searching receivers ...
- Sending notification
Receive: Notification received: Testing
- Queue empty - sleeping 500ms
- Thread waked up
- Queue empty - sleeping 500ms
- Thread waked up
- Queue empty - sleeping 500ms
* Receiver DELETED
*** No errors detected
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/7724> 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:11 UTC